14

ICollectionViewLiveShapingフィルタリングの目的でどのように実装されていますか? それは次のようなものですか:

public ICollectionView WorkersEmployed { get; set; }

WorkersEmployed = new CollectionViewSource { Source = GameContainer.Game.Workers }.View;

GetDefaultViewこのコレクションにフィルターの複数のインスタンスが必要なため、使用していません。それが重要な場合GameContainer.Game.Workersは、ObservableCollectionです。

ApplyFilter(WorkersEmployed);

private void ApplyFilter(ICollectionView collectionView)
{
    collectionView.Filter = IsWorkerEmployed;
}

public bool IsWorkerEmployed(object item)
{
    Worker w = item as Worker;
    return w.EmployerID == this.ID;
}

これはすべて機能しますが、もちろん手動で更新する必要があるため、使用しようとしていますICollectionViewLiveShaping。ライブフィルタリングはどのように機能しますか?

更新:ICollectionViewLiveShapingLiveFilteringPropertiesコレクションにプロパティを追加する唯一の方法は、文字列を使用することです。その制限を考えると、別のクラス (この場合は Workers' EmployerID) のプロパティでフィルタリングすることさえ可能ですか?

この状況で私がやろうとしていることは、実行可能な選択肢でさえありますか?

4

3 に答える 3

14

あなたがする必要があるadd a propertyのはLiveFilteringProperties、フィルタがプロパティの変更を呼び出し、コレクションに設定IsLiveFilteringすることだけです。trueto enable live filtering

PropertyChangedプロパティが変更されるたびにイベントが発生することを確認してください。EmployerIDつまり、Workerクラスが実装する必要がありますINotifyPropertyChangedEvent

これはうまくいきます -

public ICollectionViewLiveShaping WorkersEmployed { get; set; }

ICollectionView workersCV = new CollectionViewSource
                         { Source = GameContainer.Game.Workers }.View;

ApplyFilter(workersCV);

WorkersEmployed = workersCV as ICollectionViewLiveShaping;
if (WorkersEmployed.CanChangeLiveFiltering)
{
    WorkersEmployed.LiveFilteringProperties.Add("EmployerID");
    WorkersEmployed.IsLiveFiltering = true;
}
于 2013-07-28T09:26:22.013 に答える
2

WPF + MVVM + Visual Studio 2017 を使用しています。

これを変換して、ライブ フィルタリングを追加します。

public ObservableCollection<RowViewModel> Rows { get; set; }

以下の方法には、2 つの重要な利点があります。

  • 一括更新を使用して画面上のレンダリングを最小限に抑えるために、WPF ランタイムと効率的に連携するように設計されています。
  • だから速い。
  • また、ボイラープレート コードが以下にリストされているため、Web 上にある他のドキュメントに比べて簡単に理解できます。

これがうまくいったかどうか、問題があればお知らせください。簡単にするために手順を更新します。

そして手順:

ステップ 1: 非通知コレクション ラッパー

更新イベントを発生させない特別な ObservableCollection を作成します。これは 1 回限りです。update bulk update イベントを自分で起動したいので、より高速です。

public class NonNotifyingObservableCollection<T> : ObservableCollection<T>
{
    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { /* Do nothing */ }
}

ステップ 2: NonNotifyingObservableCollection に変換する

この新しいコレクションを使用するプライベート変数に変換します。

private NonNotifyingObservableCollection<RowViewModel> rows;
// ... and in constructor
rows = new NonNotifyingObservableCollection<RowViewModel>();

ステップ 3: ラッパーを追加する

次の変数を追加します。

private ICollectionView rowsView;
public ICollectionViewLiveShaping RowsLiveView { get; set; }

そして、ViewModel が構築された後の Initialise() 呼び出しで (またはおそらくコンストラクターで):

// Call on the dispatcher.
dispatcher.InvokeAsync(() =>
{
    this.rowsView = CollectionViewSource.GetDefaultView(this.rows);
    this.rowsView.Filter = o =>
        {
            // This condition must be true for the row to be visible on the grid.
            return ((RowViewModel)o).IsVisible == true;
        };
    this.RowsLiveView = (ICollectionViewLiveShaping)this.rowsView;
    this.RowsLiveView.IsLiveFiltering = true;
    // For completeness. Changing these properties fires a change notification (although
    // we bypass this and manually call a bulk update using Refresh() for speed).
    this.RowsLiveView.LiveFilteringProperties.Add("IsVisible");
});

ステップ 4: アイテムを追加する

バッキング コレクションに項目を追加し、呼び出し.Refresh()てビューを更新します。

this.rowsView.Add(new RowViewModel( /* Set properties here. */ ));

次に、グリッドを , にバインドします (元のコードでRowsLiveViewにバインドする代わりに)。Rows

ステップ 5: ライブ フィルタリングを更新する

これで、プロパティを更新してから、グリッドを再描画するためIsVisibleに呼び出します。.Refresh()

rows[0].IsVisible=false;
this.rowsView.Refresh(); // Hides the first row.

アップデート

更新:この回答は簡略化できます。の要点はICollectionViewLiveShaping、を呼び出す必要なく自動リフレッシュすること.Refresh()です。NonNotifyingObservableCollectionがあり、 を使用してすべてを手動で制御していることを考えると、 and を直接.Refresh()削除して( を使用してプロパティにし、 normal を使用します。つまり、ICollectionViewLiveShaping は少量の行 (たとえば、100 未満) に最適です。しかし、それ以上の場合は、一括更新とマニュアルを組み合わせた方が速度の点で優れています。public ICollectionViewLiveShaping RowsLiveView { get; set; }RowsView{ get; set; }ObservableCollection<>ICollectionViewRefresh()

于 2019-06-14T08:26:37.897 に答える