Question

I have run into a problem with the listpicker. I have a settings page with a option called "Decimals" where you can toggle a "Toggleswitch" and if you turn the toggle on, the listpicker gets enabled. Now when you click on the listpicker, you can choose from 1 to 5 as the amount of decimals. If you choose for example the number "3" in the listpicker, it will get saved to a key on isolated storage with the value 3, if you go to the MainPage it will check the isolatedstorage and if it contains the value "3", it will set a textblock to use 3 decimals. If I then go to my Settings page again, the app crashed with the message "SelectedIndex must always be set to a valid value." Where it should have showed the correct value that was chosen in the listpicker

Here is the code I use:

Settings.XAML:

<phone:PhoneApplicationPage
xmlns:local="clr-namespace:Vaterpas"
x:Class="Vaterpas.Settings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">

<phone:PhoneApplicationPage.Resources>
    <local:Decimals x:Key="Decimals"/>
    <DataTemplate x:Name="lpkFullItemTemplate">
        <TextBlock FontSize="36" Text="{Binding}" />
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="100"/>
        <RowDefinition Height="120"/>
        <RowDefinition Height="100"/>
        <RowDefinition Height="100"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="285">
        </ColumnDefinition>
        <ColumnDefinition>
        </ColumnDefinition>
    </Grid.ColumnDefinitions>

    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel Grid.ColumnSpan="2" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock Text="Indstillinger" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <Grid Grid.Column="2" Grid.Row="2">
        <toolkit:ToggleSwitch Click="tglDecimals_Click" VerticalAlignment="Top" Height="90" Name="tglDecimals" Content="" Margin="0,10,10,0"></toolkit:ToggleSwitch>
        <Grid DataContext="{StaticResource Decimals}">
            <toolkit:ListPicker x:Name="lpkDecimals" ItemsSource="{Binding decimals}" FullModeHeader="Antal decimaler" FullModeItemTemplate="{StaticResource lpkFullItemTemplate}" ExpansionMode="FullScreenOnly" IsEnabled="False" Margin="130,60,20,0" SelectionChanged="lpkDecimals_SelectionChanged"></toolkit:ListPicker>
        </Grid>
</Grid>

Settings.cs

namespace Vaterpas { public partial class Settings : PhoneApplicationPage {

    protected IsolatedStorageSettings m_Settings = IsolatedStorageSettings.ApplicationSettings;

    protected const string TOGGLE_DECIMALS_SETTING_KEY = "ToggleDecimals";
    protected const string DECIMALS_SETTING_KEY = "Decimals";

    public Settings()
    {
        InitializeComponent();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {

        if (m_Settings.Contains(TOGGLE_DECIMALS_SETTING_KEY))
        {
            string decimalsToggleValue = (string)m_Settings[TOGGLE_DECIMALS_SETTING_KEY];
            string decimalsValue = (string)m_Settings[DECIMALS_SETTING_KEY];

            if (decimalsToggleValue == "On") 
            {
                lpkDecimals.IsEnabled = true;
                tglDecimals.IsChecked = true;
                tblDecimals.Text = "On";

                if (decimalsValue == "1") 
                {
                    lpkDecimals.SelectedIndex = 0; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
                else if (decimalsValue == "2")
                {
                    lpkDecimals.SelectedIndex = 1; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
                else if (decimalsValue == "3")
                {
                    lpkDecimals.SelectedIndex = 2; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
                else if (decimalsValue == "4")
                {
                    lpkDecimals.SelectedIndex = 3; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
                else if (decimalsValue == "5")
                {
                    lpkDecimals.SelectedIndex = 4; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
            }
            else
            {
                tglDecimals.IsChecked = false;
                tblDecimals.Text = "Off";
                lpkDecimals.IsEnabled = false;
            }
        }
        else
        {
            tglDecimals.IsChecked = false;
            tblDecimals.Text = "Off";
        }
        base.OnNavigatedTo(e);
    }

    private void tglDecimals_Click(object sender, RoutedEventArgs e)
    {
        if (tglDecimals.IsChecked == true)
        {
            lpkDecimals.IsEnabled = true;
            tblDecimals.Text = "On";
            m_Settings[TOGGLE_DECIMALS_SETTING_KEY] = "On";
            lpkDecimals.SelectedIndex = 0;
            m_Settings[DECIMALS_SETTING_KEY] = "1";

        }
        else
        {
            lpkDecimals.IsEnabled = false;
            tblDecimals.Text = "Off";
            m_Settings[TOGGLE_DECIMALS_SETTING_KEY] = "Off";
            m_Settings[DECIMALS_SETTING_KEY] = "0";    
        }
    }

    private void lpkDecimals_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // Make sure we don't handle the event during initiation.
        if (e.RemovedItems != null && e.RemovedItems.Count > 0)
        {
            if (this.lpkDecimals.SelectedItem != null)
            {
                m_Settings[DECIMALS_SETTING_KEY] = lpkDecimals.SelectedItem.ToString();
            }
        } 

    }
}

public class Decimals
{
    public IEnumerable<string> decimals { get { return "1,2,3,4,5".Split(','); } }


}

}

ERROR: SelectedIndex must always be set to a valid value.

I really hope there is someone that can help me with this problem.

Was it helpful?

Solution

I think the the ItemSource is taking time to get assigned to the listpicker as it is assigned in xaml and OnNavigatedTo sometimes runs before InitializeComponent(); method which loads the xaml, and Selected Index property is getting assigned in OnNavigatedTo which is the reason for your error.

Remove the assignment of itemsource from .xaml and Try assigning it in OnNavigatedTo itself before all your coded stuff.

Like this :-

protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        tglDecimals.ItemSource=Your List;
        if (m_Settings.Contains(TOGGLE_DECIMALS_SETTING_KEY))
        {
            string decimalsToggleValue = (string)m_Settings[TOGGLE_DECIMALS_SETTING_KEY];
            string decimalsValue = (string)m_Settings[DECIMALS_SETTING_KEY];

            if (decimalsToggleValue == "On") 
            {
                lpkDecimals.IsEnabled = true;
                tglDecimals.IsChecked = true;
                tblDecimals.Text = "On";

                if (decimalsValue == "1") 
                {
                    lpkDecimals.SelectedIndex = 0; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
                else if (decimalsValue == "2")
                {
                    lpkDecimals.SelectedIndex = 1; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
                else if (decimalsValue == "3")
                {
                    lpkDecimals.SelectedIndex = 2; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
                else if (decimalsValue == "4")
                {
                    lpkDecimals.SelectedIndex = 3; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
                else if (decimalsValue == "5")
                {
                    lpkDecimals.SelectedIndex = 4; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.") 
                }
            }
            else
            {
                tglDecimals.IsChecked = false;
                tblDecimals.Text = "Off";
                lpkDecimals.IsEnabled = false;
            }
        }
        else
        {
            tglDecimals.IsChecked = false;
            tblDecimals.Text = "Off";
        }
        base.OnNavigatedTo(e);
    }

This Would Help

OTHER TIPS

First have a property for selected index just to check like this--

int lpkSelectedIndex=0;
public int LpkSelectedIndex
{
    get
    {
        return this.lpkSelectedIndex;
    }
    set
    {
        this.lpkSelectedIndex= value;
    }
}

After that bind this property in xaml like this.And remember bind this after Itemsource property and try it.

<toolkit:ListPicker x:Name="lpkDecimals" ItemsSource="{Binding decimals}" FullModeHeader="Antal decimaler" FullModeItemTemplate="{StaticResource lpkFullItemTemplate}" ExpansionMode="FullScreenOnly" IsEnabled="False" Margin="130,60,20,0" SelectionChanged="lpkDecimals_SelectionChanged" SelectedIndex="{Binding LpkSelectedIndex, Mode=TwoWay}"></toolkit:ListPicker>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top