简体   繁体   中英

ItemsControl rendering slowly

I am using an ItemsControl for showing alist of items and itrs xaml is like

<ItemsControl  ItemsSource="{Binding ShelfItemsCollection}" Name="shelfGridView" Margin="5" >
<ItemsControl.ItemTemplate>
        <DataTemplate>   
        <Stackpanel>                        
        <Image Width="150" Height="200" Stretch="Fill" Source="{Binding CoverImage}" ></Image> 
        +
        some other infos
        </Stackpanel>
        </DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>                    
            <WrapPanel  Orientation="Horizontal" />                    
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

The problem i am facing is i had almost 100 items in list and i am doing some filtering operations on the list based on some properties and limit the results to a lesser no ( say 20 items at a time)for doing this filtering it took a lot of time to refresh and load the list view . This is the code i used for filtering

ICollectionView dataView = CollectionViewSource.GetDefaultView(shelfGridView.ItemsSource);
dataView.Filter = CloudFilter;
dataView.Refresh();
private bool CloudFilter(object item)
{
MyObject lib = item as MyObject;
return lib.Property !=valuetofilter; 
} 

Is any way to improve the perfomance or any specific reason for slow rendering ?

ItemsControl doesn't support UI virtualization out of the box . Either use ListBox or make ItemsControl UI virtualized.

You can enable UI virtualization on ItemsControl by following some steps :

  1. Set VirtualizingStackPanel.IsVirtualizing="True" on ItemsControl.
  2. Set ItemsPanel to be VirtualizingStackPanel .
  3. Override ControlTemplate of ItemsControl and wrap ItemsPresenter inside ScrollViewer .
  4. Set ScrollViewer.CanContentScroll="True" on ItemsControl.

Details for the above proposal can be found here .


Moreover, you are setting ItemsSource directly to SourceCollection ie ShelfItemsCollection and later filtering it by getting defualtView created underneath for that collection. Binding directly with sourceCollection will force ItemsControl (non-Virtualized ofcourse) to generate 100 containers to host your underlying objects.

Instead you should create ICollectionView with filter predicate set on it and bind ItemsSource to that instance. May be you can also create CollectionViewSource and bind with it. If you bind with filtered instance, it will generate only 20 containers (non-virtualized ItemsControl). Ofcourse, enabling UI virtualization on ItemsControl, will generate containers for only visible UI items on GUI.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM