8

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

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

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

4

2 回答 2

9

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

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

于 2009-10-27T21:41:51.463 回答
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);
};
于 2012-03-15T18:38:20.690 回答