【问题标题】:Why sorting using CollectionViewSource.SortDescriptions is slow?为什么使用 CollectionViewSource.SortDescriptions 排序很慢?
【发布时间】:2010-12-10 15:52:45
【问题描述】:

这是单击DataGrid 中的列标题时的默认排序方法。当底层列表包含 100,000 个项目时,刷新视图大约需要 20 秒。在CollectionView 上设置SortDescriptions 时可以观察到相同的延迟。

使用ListCollectionView.CustomSort 或通过对列表进行排序和重新分配几乎可以立即进行排序。

为什么会出现这种延迟?这只是对绑定属性的“反射税”吗?

【问题讨论】:

    标签: wpf sorting datagrid icollectionview


    【解决方案1】:

    过滤的最佳性能调整是切换 DataGridRow Visibility。它产生了巨大的差异!

    1.将 IsVisible 属性添加到您将 DataGrid 的 ItemSource 绑定到的 Collection Item。

    private bool _isVisible = true;
    public bool IsVisible
    {
        get { return _isVisible; }
        set 
        { 
            if (_isVisible == value)
                 return;
            _isVisible = value;
            RaisePropertyChanged(()=>IsVisible);
         }
     }
    

    2.通过将 DataGridRow 绑定到您的 IsVisible 属性来触发其可见性:

    <DataGrid.ItemContainerStyle>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="Visibility" 
                    Value="{Binding Path=IsVisible, 
                                    Converter={StaticResource BoolToVisibility}}"/>
     </Style>
    </DataGrid.ItemContainerStyle>
    

    3.好吧,我猜你也必须在某个地方设置 IsVisible,比如在你的 ViewModel 中。这只是我正在做的一个示例(只是复制/粘贴工作) - 基本上根据我的其他 ViewModel 中的某些标准将 IsVisible 设置为 true 或 false:

    FilterViewModel.OnFilter += (s, a) =>
    {
        foreach (Row row in ViewModel.Rows)
        row.IsVisible = !FilterViewModel.FilteringItems.Any(item => 
                                       item.IsSelected && item.Name == row.Name);
    };
    

    【讨论】:

    • 这对我有用。顺便说一句,这就是在 Angular 中解决类似问题的方法:)。
    【解决方案2】:

    你是对的,这是一种反射税。前段时间我非常仔细地研究了 DataGrid 的性能,而反射在这里是一个瓶颈。无论排序算法有多快,它们都不会在两次比较之间缓存属性值。因此,即使您有 n*ln(n) 比较,在 n == 100 000 的情况下,您也会得到 ~1 000 000 次操作。每个操作数都使用反射来获取价值,因此您有 2 000 000 次调用反射税 :) ...ListCollectionView.CustomSort 是这里的理想解决方案。

    PS:最后,我们写了基于 ListView 的网格,因为我们对 DataGrid 的渲染性能也不满意……但那是另一回事了 :)

    【讨论】:

    • 这适用于实时排序吗? (ListCollectionView.LiveSortingProperties)
    猜你喜欢
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 2010-10-30
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多