8

これは、 の列ヘッダーをクリックしたときのデフォルトの並べ替え方法ですDataGrid。基になるリストに 100,000 項目が含まれている場合、ビューを更新するのに約 20 秒かかります。SortDescriptionにs を設定すると、同じ遅延が観察されますCollectionView

リストを使用するListCollectionView.CustomSortか、並べ替えて再割り当てすることによる並べ替えは、ほぼ瞬時に機能します。

この遅れはなぜですか?これは、バインドされたプロパティに対する単なる「反射税」ですか?

4

2 に答える 2

9

そうです、これは反射税です。少し前に DataGrid のパフォーマンスを詳しく調べたところ、リフレクションがボトルネックでした。ソートアルゴリズムがどれほど高速であっても、2 つの比較の間でプロパティの値をキャッシュしません。したがって、n*ln(n) の比較がある場合でも、n == 100 000 の場合、~1 000 000 の操作が得られます。各オペランドはリフレクションを使用して値を取得するため、tax でリフレクションを 2 000 000 呼び出す必要があります :) ...ListCollectionView.CustomSortここでは理想的なソリューションです。

PS: 結局のところ、DataGrid のレンダリング パフォーマンスにも満足できなかったため、ListView ベースのグリッドを作成しました... しかし、それは別の話です :)

于 2009-10-27T21:41:51.463 に答える
1

フィルタリングの最適なパフォーマンス調整は、DataGridRow の可視性を切り替えることでした。それは違いの大きさを作りました!

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. IsVisible プロパティにバインドして、DataGridRow の可視性をトリガーします。

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

3.そうですね、ViewModel のように、IsVisible をどこかに設定する必要があります。これは私がやっていることのほんの一例です(ジョブをコピーして貼り付けるだけです)-基本的に、他の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 に答える