Items控制渲染缓慢

Jib*_*hew 2 wpf itemscontrol wpf-controls c#-4.0

我正在使用 ItemsControl 来显示项目列表,itrs 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>
Run Code Online (Sandbox Code Playgroud)

我面临的问题是我的列表中有近 100 个项目,我正在根据某些属性对列表进行一些过滤操作,并将结果限制为较小的否(例如一次 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; 
} 
Run Code Online (Sandbox Code Playgroud)

有什么方法可以提高性能或渲染速度慢有什么具体原因吗?

Roh*_*ats 5

ItemsControl 不支持开箱即用的 UI 虚拟化。使用 ListBox 或使 ItemsControl UI 虚拟化。

您可以通过以下一些步骤在 ItemsControl 上启用 UI 虚拟化:

  1. 在 ItemsControl 上设置VirtualizingStackPanel.IsVirtualizing="True"
  2. 设置ItemsPanelVirtualizingStackPanel.
  3. 覆盖ControlTemplateItemsControl 并包装ItemsPresenterScrollViewer.
  4. 在 ItemsControl 上设置ScrollViewer.CanContentScroll="True"

上述提案的详细信息可在此处找到。


此外,您直接设置ItemsSource为 SourceCollection ie ShelfItemsCollection,然后通过为该集合创建的 defualtView 来过滤它。直接与 sourceCollection 绑定将强制ItemsControl(当然是非虚拟化)生成 100 个容器来托管底层对象。

相反,您应该创建ICollectionView并在其上设置过滤谓词并绑定ItemsSource到该实例。也许您也可以创建CollectionViewSource它并与之绑定。如果您与过滤实例绑定,它将仅生成 20 个容器(非虚拟化 ItemsControl)。当然,在 ItemsControl 上启用 UI 虚拟化将仅为 GUI 上可见的 UI 项目生成容器。

  • @Konrad 也许更好的措辞是“不支持开箱即用的 UI 虚拟化” (3认同)