我正在使用ItemsControl来显示项目的列表,而它的xaml就像是
<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>
我面临的问题是我在列表中有近100个项目,我正在基于某些属性对列表进行一些过滤操作,并将结果限制为较小的no(比如一次说20项)进行此过滤刷新并加载列表视图需要花费大量时间。 这是我用于过滤的代码
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;
}
有没有办法改善性能或缓慢渲染的任何特定原因?
答案 0 :(得分:1)
ItemsControl
不支持UI virtualization
。使用ListBox或使ItemsControl UI虚拟化。
您可以按照以下步骤在ItemsControl上启用UI虚拟化:
VirtualizingStackPanel.IsVirtualizing="True"
。ItemsPanel
设为VirtualizingStackPanel
。ControlTemplate
ItemsControl并将ItemsPresenter
包裹在ScrollViewer
内。ScrollViewer.CanContentScroll="True"
。可以找到上述提案的详细信息here。
此外,您将ItemsSource
直接设置为SourceCollection,即ShelfItemsCollection
,然后通过在该集合下面创建defualtView来过滤它。直接与sourceCollection绑定将强制ItemsControl
(非虚拟化程序)生成100个容器来托管您的底层对象。
相反,您应该创建ICollectionView
并在其上设置过滤谓词,并将ItemsSource
绑定到该实例。也许你也可以创建CollectionViewSource
并与之绑定。如果与已过滤的实例绑定,则它将仅生成20个容器(非虚拟化的ItemsControl)。
当然,在ItemsControl上启用UI虚拟化,将仅为GUI上的可见UI项生成容器。