19

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

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

[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}" />

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

4

2 に答える 2

21

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);

これは、コレクションごとに更新することを心配することなく、プロジェクト全体で再利用できますPropertyChangedMyCollectionViewあなたのためにそれautomaticallyをします。

また

.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;
}
于 2013-07-28T08:34:53.817 に答える
11

.Net 4.5 の場合: :と呼ばれる、この機能を実現するのに役立つ新しいインターフェイス があります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 Filter not refreshed when Source is changed

于 2013-07-25T07:23:09.237 に答える