web-dev-qa-db-ja.com

ICollectionViewフィルターを自動的に更新します

関連する変更が行われたときにRefresh()を呼び出さなくても、ICollectionViewのフィルターを自動的に更新する方法はありますか?

私は次のものを持っています:

[Notify]
public ICollectionView Workers { get; set; }

このプロパティの[Notify]属性はINotifyPropertyChangedを実装するだけですが、この状況では何もしていないようです。

Workers = new CollectionViewSource { Source = DataManager.Data.Workers }.View;

Workers.Filter = w =>
    {
        Worker worker = w as Worker;
        if (w == null)
            return false;
        return worker.Employer == this;
    };

XAMLの場合:

<TextBlock x:Name="WorkersTextBlock"
           DataContext="{Binding PlayerGuild}"
           FontFamily="Pericles"
           Text="{Binding Workers.Count,
                          StringFormat=Workers : {0},
                          FallbackValue=Workers : 99}" />

pdate:ICollectionViewを使用する必要があるようですので、このトピックをもう一度見てみたいと思います。私はこの質問に報奨金を追加します。その受信者は、手動で更新する必要のない「ハンズオフ」ICollectionViewを実装する方法について何らかの洞察を提供できる人です。この時点で、私はどんなアイデアにもオープンです。

16
Jason D

AFAIKには、基になるソースコレクションのプロパティ変更時にコレクションを更新するためのICollectionViewの組み込みサポートはありません。

ただし、ListCollectionViewをサブクラス化して、refresh collection on any property changedに独自の実装を与えることができます。サンプル -

public class MyCollectionView : ListCollectionView
{
    public MyCollectionView(IList sourceCollection) : base(sourceCollection)
    {
        foreach (var item in sourceCollection)
        {
            if (item is INotifyPropertyChanged)
            {
                ((INotifyPropertyChanged)item).PropertyChanged +=
                                                  (s, e) => Refresh();
            }
        }
    }
}

このようにプロジェクトでこれを使用できます-

Workers = new MyCollectionView(DataManager.Data.Workers);

これは、PropertyChangedごとにコレクションを更新することを心配することなく、プロジェクト全体で再利用できます。 MyCollectionViewautomaticallyを実行します。

[〜#〜]または[〜#〜]

。Net4.5を使用している場合は、説明されているようにICollectionViewLiveShaping実装を使用できます ここ

私はあなたの問題の実装部分をここに投稿しました- ICollectionViewLiveShapingの実装

その投稿からの作業コード-

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;
}
18
Rohit Vats

。Net 4.5の場合:この機能の実現に役立つnewインターフェイスがあります。 ICollectionViewLiveShaping

から MSDNリンク

ライブソート、グループ化、またはフィルタリングが有効になっている場合、データが変更されると、CollectionViewはCollectionView内のデータの位置を再配置します。たとえば、アプリケーションがDataGridを使用して株式市場の株式を一覧表示し、株式が株式価値でソートされているとします。株式のCollectionViewでライブソートが有効になっている場合、株式の値が別の株式の値よりも大きくなったり小さくなったりすると、DataGrid内の株式の位置が移動します。

上記のインターフェイスの詳細: http://www.jonathanantoine.com/2011/10/05/wpf-4-5-%E2%80%93-part-10-live-shaping/


。Net 4以下の場合:SO QAに役立つ可能性のある別の投稿もあります: ソースが変更されてもCollectionViewSourceフィルターは更新されません

10
VS1