1

Closed

Listpicker randomly skips rendering items when bound to large data

description

I have a project that requires binding a list of strings to a listpicker control. When the binding is done (either in Loaded or OnNavigatedTo events), the listpicker opens to show the bound items, but some items are randomly missing (in fullscreen mode). When the listpicker starts closing, the missing items seem to appear.
 
Issue posted on stackoverflow: http://stackoverflow.com/questions/10187829/wp7-listpicker-not-showing-all-items
 
I have also attached a sample project. Please check it out.

file attachments

Closed Sep 5, 2012 at 11:37 PM by RohanTha
Closing fixed issues.

comments

wieser_software wrote May 1, 2012 at 4:01 PM

I see the same issue with 15 items. The problem appears when scrolling. I think it may have to do with recycling the items.

Here's my code fragment, when filled with 15 items with values 5-75

<StackPanel x:Name="selectSpeeds" Visibility="Collapsed">
                    <StackPanel.Resources>
                    <DataTemplate x:Name="SpeedPickerItemTemplate">
                            <Grid Height="96" Width="96" Margin="12">
                                <Ellipse HorizontalAlignment="Center" VerticalAlignment="Center"
                                         Height="96" Width="96" Fill="Red" />
                                <Ellipse HorizontalAlignment="Center" VerticalAlignment="Center"
                                         Height="72" Width="72" Fill="White" />
                                <TextBlock Text="{Binding value}" Margin="0,-3,0,0" 
                                           FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center"
                                           Foreground="Black" FontWeight="Bold" />
                            </Grid>
                    </DataTemplate>
                    <DataTemplate x:Name="SpeedPickerFullModeItemTemplate">
                            <Grid>
                                <Ellipse HorizontalAlignment="Center" VerticalAlignment="Center"
                                         Height="72" Width="72" Fill="Red" />
                                <Ellipse HorizontalAlignment="Center" VerticalAlignment="Center"
                                         Height="60" Width="60" Fill="White" />
                                <TextBlock Text="{Binding value}"  
                                           FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center"
                                           Foreground="Black" />
                            </Grid>
                        </DataTemplate>
                    </StackPanel.Resources>

                    <TextBlock Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap">
                        An alarm will sound if you are travelling faster than the speed below:
                    </TextBlock>
                    <toolkit:ListPicker x:Name="speedLimit" Header="speed limit" 
                                        FullModeHeader="Speed Limit"
                                        ItemTemplate="{StaticResource SpeedPickerItemTemplate}"
                                        FullModeItemTemplate="{StaticResource SpeedPickerItemTemplate}"
                                        >

                    </toolkit:ListPicker>

                </StackPanel>

wieser_software wrote May 4, 2012 at 1:00 PM

On further investigation, it appears that there's a race to Set (or not) the RotationX property in ListPickerPage.xaml.cs

Dispatcher.BeginInvoke(UpdateOutOfViewItems) is scheduled, and then the animation is begun. But items that scroll into view in the meantime are left with their RotationX set to the initial -90.

girishnuli wrote May 6, 2012 at 7:01 AM

@wieser_software - Thank you for looking into this. I applied the patch on the november build of the toolkit and tested with the test project attached earlier (after updating the references). The issue still exists.

wieser_software wrote May 6, 2012 at 8:08 AM

@girishnuli have you decompiled the version built into your xap to be certain the changes were applied. I've had problems with stale references to the toolkit hanging around.

shawnoster wrote May 7, 2012 at 1:02 AM

I've attached a solution I believe to be the right fix that I'll be updating the source with. If you want to give it a whirl and see if it fixes the issue you're seeing I'd be very grateful. If this works for you and it passes our tests I'll update the code on Monday.

Thanks.

wieser_software wrote May 7, 2012 at 6:30 AM

Thanks for the fix @shawnoster

I've tested it here, and the problem goes away. It's a much better version than the original in that it now only sets the rotation to -90 on visible items in the first place, and doesn't waste time setting up invisible items.

I am concerned though that when you get to the OnLoaded handler, are you guaranteed that
IList<WeakReference> itemsInView = ItemsControlExtensions.GetItemsInViewPort(Picker);

will get the visible items? I'm concerned that it might return fewer than there actually are.

Also, the IsOpen backing dependency property appears to have a typo (actually a paste into the middle):
isOIsOpenpen

wrote May 7, 2012 at 9:58 PM

Fixed on changeset 76120

shawnoster wrote May 7, 2012 at 10:08 PM

Thanks for testing the fix. I did some more work on it and discovered that there are still edge cases where the boundary item will get "missed" in the animation pass. The solution I've gone with is to keep track of all the items that have been given an animation. So far checking for the visible items in OnLoaded is working as expected but feel free to open a bug if you see issues with this.

The fix has been checked in.

shawnoster wrote May 7, 2012 at 10:30 PM

Also thanks for reporting the typo, I just checked in a fix for that as well.