0
votes

I have a ListPicker in my Windows Phone 7 app where both the ItemsSource and SelectedIndex properties are bound to my ViewModel. SelectedIndex is using Two Way binding. The items and the SelectedIndex are correctly populated on application startup. However, when I modify the SelectedIndex property in my ViewModel the ListPicker's TextBox goes blank, as if there was no selected item. If I go to full mode and check which is the selected item from the list, the correct item is being selected.

Here is the ListPicker xaml code:

<toolkit:ListPicker Name="TheListPicker" ItemsSource="{Binding TheItems}" CacheMode="BitmapCache" FullModeHeader="{Binding Path=Resources.TheHeader, Source={StaticResource LocalizedStrings }}" SelectedIndex="{Binding TheCurrentIndex, Mode=TwoWay}" IsEnabled="{Binding IsViewEnabled}" TabIndex="0" >
    <toolkit:ListPicker.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <TextBlock Text="{Binding Name}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="{StaticResource PhoneFontSizeMediumLarge}" />
            </StackPanel>
        </DataTemplate>
    </toolkit:ListPicker.ItemTemplate>
    <toolkit:ListPicker.FullModeItemTemplate>
        <DataTemplate>
            <StackPanel x:Name="item" Orientation="Horizontal" Margin="5, 24, 0, 24">
                <TextBlock Margin="15, 0, 0, 0" Text="{Binding Name}" FontSize="40" TextWrapping="Wrap" />
            </StackPanel>
        </DataTemplate>
    </toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>

This is a simplified version of my ViewModel:

[DataMember]
public ObservableCollection<ItemEntity> TheItems
{
    get
    {
        if (this.theItems == null)
        {
            this.theItems = new ObservableCollection<ItemEntity>();
        }

        return this.theItems;
    }
    set
    {
        this.theItems = value;
    }
}

[DataMember]
public int TheCurrentIndex
{
    get 
    {
        return this.theCurrentIndex;
    }
    set
    {
        if (value != this.theCurrentIndex)
        {
            this.theCurrentIndex = value;
            NotifyPropertyChanged("TheCurrentIndex");
            NotifyPropertyChanged("IsSomeOtherPropertyEnabled");
        }
    }
}

And here is the relevant code from MainPage.xaml.cs (App_ViewModelChanged is an event handler invoked when some async stuff performed on application startup finishes):

private void App_ViewModelChanged(object sender, ViewModelChangedEventArgs e)
{    
    BindToViewModel();
}

private void BindToViewModel()
{
    this.DataContext = this.ViewModel;
    this.ViewModel.IsViewEnabled = true;
}

private void SomeAsyncMethodCompleted(object sender, DetectCompletedEventArgs e)
{
    if (e.Error == null)
    {
        this.ViewModel.TheCurrentIndex = e.Result;
    }
}

This issue is not happening all the time. Happens like 50% of the time. It seems to happen only once in the application lifetime and then never happens again. Also, the issue started appearing when I switched from the Feb 2011 release of the Silverlight Control Toolkit to the Aug 2011 release. Never had this issue before.

Is this a known issue?

1
Are you sure you don't want SelectedItem instead? - Derek Beattie
I started using SelectedIndex with the hope that it would solve this same issue that was happening when using SelectedItem. So it pretty much doesn't matter which one you use. - Julio Casal
Could you share some code with us, maybe that could help solve the problem - BigL
Just added some code. Very simplified from the real version, but enough to get the idea. - Julio Casal
I try to find out what type you get from DetectCompletedEventArgs.Result, but i seem to find only examples where you get a string and not an int, but maybe that depends on your AsyncMethod. - BigL

1 Answers

0
votes

Ok, so the reason for this strange behavior was a small change in the ListPickerItem style in Aug 2011 Silverlight Control Toolkit.

This is how it looks in Aug 2011 release:

<Style TargetType="controls:ListPickerItem">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="Padding" Value="8 10"/>
    <Setter Property="Template">
        <!-- More Stuff Here -->
    </Setter>
</Style>

And this is how it looked in Feb 2011 release:

<Style TargetType="controls:ListPickerItem">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="Padding" Value="8 6"/>
    <Setter Property="Template">
        <!-- More Stuff Here -->
    </Setter>
</Style>

See the difference? They changed the ListPickerItem Padding to 8 10 in the new release and somehow that was causing the issue. Reverting to 8 6 fixes it. Don't ask me why.

So in my project I didn't actually modified the control toolkit Generic.xaml file, but just modified the specific ListPicker resources to specify a new padding for the ListPickerItem style, like this:

<toolkit:ListPicker Name="TheListPicker" ItemsSource="{Binding TheItems}" CacheMode="BitmapCache" FullModeHeader="{Binding Path=Resources.TheHeader, Source={StaticResource LocalizedStrings }}" SelectedIndex="{Binding TheCurrentIndex, Mode=TwoWay}" IsEnabled="{Binding IsViewEnabled}" TabIndex="0" >           
    <toolkit:ListPicker.Resources>
        <Style TargetType="toolkit:ListPickerItem">
            <Setter Property="Padding" Value="8 6"/>
        </Style>
    </toolkit:ListPicker.Resources>
    <toolkit:ListPicker.ItemTemplate>           
        <DataTemplate>           
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">           
                <TextBlock Text="{Binding Name}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="{StaticResource PhoneFontSizeMediumLarge}" />           
            </StackPanel>           
        </DataTemplate>           
    </toolkit:ListPicker.ItemTemplate>           
    <toolkit:ListPicker.FullModeItemTemplate>           
        <DataTemplate>           
            <StackPanel x:Name="item" Orientation="Horizontal" Margin="5, 24, 0, 24">           
                <TextBlock Margin="15, 0, 0, 0" Text="{Binding Name}" FontSize="40" TextWrapping="Wrap" />           
            </StackPanel>           
        </DataTemplate>           
    </toolkit:ListPicker.FullModeItemTemplate>           
</toolkit:ListPicker>

Such a small change!