0

Entity Framework は、ChangeTracker.State というプロパティを持つ追跡可能なエンティティを提供します。これを使用して、エンティティが削除されているかどうかを識別できます。

私たちのリストでは、削除されたエンティティを表示したくありません。

どちらが速いですか?

方法 1: CollectionViewSource.Filter を使用してレコードをテストおよび削除する

<CollectionViewSource Filter="ViewSource_Filter" />

private void ViewSource_Filter(object sender, FilterEventArgs e)
{
    var _Item = e.Item as ITrackableEntity;
    e.Accepted = _Item.ChangeTracker.State != ObjectState.Deleted;
}

方法 2: DataTrigger を ItemTemplate.DataTemplate に追加して、項目をテストおよび非表示にする

<DataTemplate.Resources>
    <Style TargetType="{x:Type DockPanel}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ChangeTracker.State}">
                <DataTrigger.Value>
                    <entities:ObjectState>Deleted</entities:ObjectState>
                </DataTrigger.Value>
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</DataTemplate.Resources>

ありがとう。

4

3 に答える 3

2

この問題に関連する ItemsControl があると仮定すると、個人的には collectionview ベースのフィルターが気に入っています。

理由...

  1. そのフィルタリングは ViewModel の手に委ねられています。そのため、コレクション ビューを更新するたびに、再度フィルター処理が行われます。

  2. ChangeTracker.StateUI のライフサイクル全体でプロパティが設定されるだけで更新されない場合、コレクション ビューはレンダリング時に 1 回だけフィルタリングされます。一方、DataTriggers は、ChangeTracker.State発生する可能性がある/発生しない可能性がある変更を待機します。

  3. この CollectionView が適用される ItemsControl の代替アイテム行スタイルは、データ トリガーで正しく効果を発揮しません。アイテムを非表示にするだけで、代替行スタイルを調整しないため、collectionview 自体が事前にアイテムを除外します。つまり、1 行おきの行を灰色の背景にする必要がある場合、DataTrigger を使用すると、隣接する 2 つの行が灰色になることがあります。

  4. DataTriggers は、仮想化されていないアイテムに対してのみ有効になります。これにより、スクロール バーのヒューリスティックが失敗する可能性がありますDeleted。それらにスクロールします。したがって、この間、スクロールバーは再計算され、実際のスクロール値を調整するためにちらつきます。そのため、スクロールに適用できるアイテムが 100 個あるように見えるかもしれませんが、実際にはスクロールするのに 50 個のアイテムしか必要ありません。

CollectionView は、50 個のアイテムを提供して、ビューをスクロールする前にそれ自体を表示します。

パフォーマンスに関する限り、まさにこれが原因で、DataTrigger は、項目が非仮想化された場合、つまりスクロール ビューに持ち込まれた場合にのみ適用されるという事実により、より高速になります。しかし、それは上記の問題を引き起こす可能性があります。

これが役立つかどうか教えてください。

于 2011-08-26T08:00:34.053 に答える
0

方法 1が正解です。

于 2011-09-07T20:14:29.613 に答える
0

ただし、Loaded イベントには必要な情報が含まれている場合があります。MSDN から: Loaded イベントは、最終的なレンダリングの前に発生しますが、レイアウト システムがレンダリングに必要なすべての値を計算した後で発生します。ロードは、要素が含まれる論理ツリーが完成し、HWND とレンダリング サーフェスを提供するプレゼンテーション ソースに接続することを伴います。私の解釈では、フィルターとトリガーは処理されていますが、肯定的ではありません。Unloaded は最終的な数値ではありませんが、リンゴとリンゴを比較していると思います。しかし、それでもリンゴは適切な比較対象ではないかもしれません。デバッガーが XAML をウォークした場合は、とてもいいでしょう。デバッガーは XAML をウォークしないため、トリガーを直接測定することはできないと思います。最良の希望は、ページを測定することです。難しいフィルターだけでページを作成します。

    public MainWindow()
    {
        Debug.WriteLine(DateTime.Now.ToLongTimeString());
        InitializeComponent();
        Debug.WriteLine(DateTime.Now.ToLongTimeString());
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine(DateTime.Now.ToLongTimeString());

デバッグはストレート実行と同じではないため、これら 3 回を TextBlocks にバインドします。また、XAML で定義されているフィルターと比較することもできます。私の直感では、どちらも非常に高速になるため、違いを知るのは難しいですが、フィルターの方が高速であると思います。

于 2011-08-25T17:13:20.027 に答える