2

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 ?

Sebastian
  • 4,625
  • 17
  • 76
  • 145
  • Are you using filter to limit the items as 20? – Vimal CK Mar 07 '14 at 06:04
  • Limit the items based on some properties , u can see CloudFilter() , Based on a property value , for example if property.Contains("Japan") , then it shows only records related to term Japan ,Its not necessary that the count is going to be 20. i edited the question as well – Sebastian Mar 07 '14 at 06:14
  • Post more code let us test with your example and your data structure. – dev hedgehog Mar 07 '14 at 07:25
  • http://pastebin.com/3CRBLnU2 Here is the code of xaml and c# . Hav to use some hardcoded values for testing . – Sebastian Mar 07 '14 at 08:13

1 Answers1

5

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 i.e. 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.

Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • "ItemsControl doesn't support UI virtualization" "Either use ListBox or make ItemsControl UI virtualized.". If it doesn't support virtualization how can you make it UI virtualized. Doesn't make sense. – Konrad Apr 15 '19 at 08:05
  • 3
    @Konrad perhaps a better phrasing would be, "does not support UI virtualization out of the box" – gusmally supports Monica Feb 20 '20 at 21:31