web-dev-qa-db-ja.com

ObservableCollectionのアイテムが変更されたかどうかを検出する方法

ObservableCollection<Product>にバインドされているデータグリッドがあります。グリッドが更新されると、コレクション内のProductオブジェクトが自動的に更新されます。

私が今やりたいのは、コレクション内のオブジェクトが更新されたときにトリガーされるようなもの、または製品が更新された場合にtrue/falseの依存関係を返すコレクションへのある種のバインディングです。

全体的な目的は、コレクションに変更が加えられていない場合は無効にし、変更が加えられている場合は有効にする保存ボタンをメインウィンドウに配置することです。

INotifyPropertyChangeを読みましたが、これを使用してコレクション全体の変更を監視する方法がわかりません。

さらに、このインターフェイスをProductクラスに実装すると、UIがコレクション内のすべての製品を監視する方法がわかりません。

20
Remotec
  • INotifyPropertyChangedクラスにProductを実装し、すべてのプロパティに通知を送信します。
  • ビューモデルにINotifyPropertyChangedを実装します。
  • プロパティIsDirtyをViewModelに追加します(INotifyPropertyChangedを介した通知付き)。
  • ビューモデルで、CollectionChangedにサブスクライブします

    public YourViewModel()
    {
        ...
        YourCollection.CollectionChanged += YourCollection_CollectionChanged; 
        ...
    }
    
    private void YourCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args)
    {
        if (args.OldItems != null)
            foreach(var oldItem in args.OldItems)
                oldItem.PropertyChanged -= YourItem_PropertyChanged;
    
        if (args.NewItems != null)
            foreach(var newItem in args.NewItems)
                newItem.PropertyChanged += YourItem_PropertyChanged;
    }
    
    private void Youritem_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs args)
    {
        IsDirty = true;
    }
    
  • これで、ビューモデルのIsDirtyプロパティにバインドできます。たとえば、Button.IsEnabledプロパティを直接バインドできます。

15
chopikadze

ObservableCollectionを使用するだけです。 CollectionChangedというイベントがあります。登録すれば、やりたいことができます。例:

ObservableCollection<string> strings = new ObservableCollection<string>();
strings.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(changed);
strings.Add("Hello");
strings[0] = "HelloHello";

そして:

private void changed(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args)
{
    //You get notified here two times.
}
2
Skalli

ロジックはモデル(Productクラス)に含める必要があります。クリーンなアプローチは、モデルのIsDirtyプロパティ(フィールドに基づく)を公開することです。

また、ViewModelにはCanSaveが内部コレクションをチェックするコマンドバインディングがあり、コレクションIsDirty=true内のアイテムのいずれかがあればtrueを返します。

1

コレクション内の各オブジェクトのPropertyChangedイベントをサブスクライブし、このイベントを、たとえばオブジェクトのセッターで発生させることは機能すると思います。

ただし、グリッド内のセルが変更されているかどうかを判断するために、これらすべてを行う必要はないと思います。代わりに、彼らがここで行うようなことを行うことができると思います。

http://social.msdn.Microsoft.com/Forums/en/wpf/thread/81131225-90fb-40f9-a311-066952c7bc4

0
Orkun Ozen