Nested Listbox with lot of images is jittering and

2019-08-21 18:46发布

问题:

I have been now banging my head two days for getting nested listbox working, where I have like categories vertically and then the images horizontally. Amount of images can be easily 1000-2000. Here is my XAML code for it:

        <ListBox x:Name="CategoryList"  VirtualizingStackPanel.VirtualizationMode="Recycling">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Grid Height="100" Width="480">
                            <Image HorizontalAlignment="Left" Width="80" Height="80" Margin="0,20,0,0" Source="/Images/listicons14.png"/>
                            <Rectangle HorizontalAlignment="Right" Width="390" Height="80" VerticalAlignment="Bottom" Fill="#FF7BB800"/>
                            <TextBlock Text="{Binding Category}" Margin="121,45,0,25" HorizontalAlignment="Left" Width="100"/>
                        </Grid>
                        <ListBox VirtualizingStackPanel.VirtualizationMode="Recycling" ItemsSource="{Binding Advertisements}" x:Name="Advertisement" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled">
                            <ListBox.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <VirtualizingStackPanel Orientation="Horizontal"/>
                                </ItemsPanelTemplate>
                            </ListBox.ItemsPanel>
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Height="220" Width="300">
                                        <Border BorderBrush="#FF7BB800" BorderThickness="3" HorizontalAlignment="Center" Width="275" Height="190" VerticalAlignment="Center">
                                            <Image Source="{Binding AdvertisementImage}" Width="275" Height="190"/>
                                        </Border>
                                    </StackPanel>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                        </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

and here is how I'm filling it now (this is as a debugging purposes to use just three different pictures to fill up it. Size of the pictures are about 70kb, but I tested very small jpeg as well (10kb each of them) and it didn't have any impact.

        for (int i = 0; i < 20; i++)
        {
            ProductCategory productcategory = new ProductCategory { Category = "Book" + i.ToString() };
            productcategory.Advertisements = new List<Advertisement>();
            for (int j = 0; j < 10; j++)
            {
                productcategory.Advertisements.Add(new Advertisement { AdvertisementImage = new Uri("/Images/advGalaxyS2reduced.jpg", UriKind.Relative) });
                productcategory.Advertisements.Add(new Advertisement { AdvertisementImage = new Uri("/Images/adviphone4sreduced.jpg", UriKind.Relative) });
                productcategory.Advertisements.Add(new Advertisement { AdvertisementImage = new Uri("/Images/advLumia800reduced.jpg", UriKind.Relative) });

            }
            productcategories.Add(productcategory);
        }
        this.CategoryList.ItemsSource = productcategories;

I have tested this also with Telerik's Listbox and it is definitely better but not "sellable", so I'm still wondering am I missing some more here. In my mind virtualization for data is ON if I'm looking the amount of RAM it is eating. Please help me out here:)

回答1:

I suspect that it is the nested listboxes that are causing the problem as the layout engine will need to contantly be re-measuring everything as you scroll. I'd look to change the layout to one which has a fixed item size and then see if you still have the same issues.

Here are some other more general pointers:

  • 1000 images is a lot to try and display at once. If you try to do this you'll have resource issues which, at best, will impact overall performance.
  • You should always aim to use images of the size they will be displayed on the device. This saves time (and processing resources) in: downloading (if appropriate) no more bytes than are needed, loading no more bytes than are needed and not having to resize.
  • Large numbers of anything on a small screen are hard for the user to naivigate and find what they are looking for. It is generally recommended (there are a few exceptions) that you break down the large lists into smaller categories.
  • If you want to have a very large list (or a list of unknown size) displayed you should virtualize the data. This requires having only a subset of the data loaded at any one time (and swapping out was is loaded as the user navigates through the data) and thereby saving lots of time and resources.
  • Always test to ensure that your data is being virtualized by monitoring when items are loaded and unloaded.


回答2:

1000 images are a lot..as stated by others as well.. try the lowProfileImage loader
http://blogs.msdn.com/b/delay/archive/2010/09/02/keep-a-low-profile-lowprofileimageloader-helps-the-windows-phone-7-ui-thread-stay-responsive-by-loading-images-in-the-background.aspx

Its not the exact solution to your problem but it may give you and idea about performance improvement