2011-07-06 16 views
4

さて、ObservableCollectionにバインドするXAMLファイルにItemsControlがあります。 ObservableCollectionはビューモデルクラス(このクラスをViewModelAと呼ぶ)にあり、ObservableCollectionの各アイテムはという別のビューモデルクラス(ViewModelBクラスを呼び出しましょう)のインスタンスです。観察可能なコレクション内のアイテムのプロパティが変更されたことを通知するにはどうすればよいですか?

ViewModelAにプロパティがあり、変更された場合、間接的には、ViewModelBクラスの多くのインスタンスにあるプロパティの値を変更します。つまり、ViewModelBに直接行かず、そのプロパティを設定してINotifyPropertyChange呼び出しを引き起こすのではなく、モデルにいくつかのプロパティを設定し、モデルの変更がViewModelBが表示するものに影響します景色。

ViewModelBの何かが変更されたことをビューに通知するにはどうすればよいですか?

答えて

2

ビューにはコレクションが変更されたことを伝えることができ、コレクション全体にリバインドしてビューを更新することができます。

モデルにINotifyPropertyChangedが実装されている場合は、ViewModelBクラスでラップされたモデルの変更をリッスンし、必要に応じてプロパティ変更イベントを発生させることもできます。

+0

1を含むフレームワークの多くにイベントアグリゲータの詳細情報を見つけることができます。あなたの答えは質問よりもはっきりしているので、私は一般的なケースを繰り返し述べます:変更のビューを通知する2つの方法は、 'INotifyCollectionChanged'と' INotifyPropertyChanged'です。しかし、あなたのビューモデルが相互依存している場合は、あなたのビューモデルでそれらのインタフェースを消費し、必要に応じて通知をバブルアップすることは完全に当​​然です。 –

+1

ここで重要な点は、コレクションそのものは変更されていないことです。そのため、INotifyCollectionChangedは良くありません。しかし、私はモデルクラスにINotifyPropertyChangedを実装することができるので、うまくいくように見えます。助けてくれてありがとう! – David

0

これを解決するために、私は、VeryObservableCollectionというクラスを作成しました。追加するオブジェクトごとに、オブジェクトのNotifyPropertyChangedイベントをCollectionChangedイベントをトリガーするハンドラーにフックします。削除されたオブジェクトごとに、ハンドラが削除されます。非常に簡単で、あなたが望むものをまさにあなたに与えるでしょう。部分コード:

public class VeryObservableCollection<T> : ObservableCollection<T> 

/// <summary> 
/// Override for setting item 
/// </summary> 
/// <param name="index">Index</param> 
/// <param name="item">Item</param> 
protected override void SetItem(int index, T item) 
{ 
    try 
    { 
     INotifyPropertyChanged propOld = Items[index] as INotifyPropertyChanged; 
     if (propOld != null) 
      propOld.PropertyChanged -= new PropertyChangedEventHandler(Affecting_PropertyChanged); 
    } 
    catch (Exception ex) 
    { 
     Exception ex2 = ex.InnerException; 
    } 
    INotifyPropertyChanged propNew = item as INotifyPropertyChanged; 
    if (propNew != null) 
     propNew.PropertyChanged += new PropertyChangedEventHandler(Affecting_PropertyChanged); 

    base.SetItem(index, item); 
} 
0

モデルの変化がViewModelBのいくつかのプロパティおよびそれらの特性に変化する場合UI(すなわちViewModleBがINotifyPropertyChangedのに実装されている)に通知を変更有し、変更は即座にUIに反映します。

したがって、別のviewmodelBのObservableCollectionがある場合、そのviewmodelBのプロパティ変更のイベントをフックアップする必要はありません。私の理解によると、誰でもviewmodelBのプロパティ(モデルクラスまたは他の誰か)を変更し、プロパティに変更通知がある場合、ビューは自動的に更新されます。

1

Reed Copseyのようにするのが理想です...モデルにINotifyPropertyChangedを実装し、ViewModelBでそれらのイベントをリッスンさせます。 ViewModelBは、更新がどこに起こっても、変更を取得します。

ただし、モデルによってはINotifyPropertyChangedが実装されていない(またはできない)ことがあります。この場合、Event Aggregatorパターンを使用して、ViewModelAインスタンスとViewModelBインスタンスの間でメッセージを渡すことを検討することをお勧めします。

この場合、ViewModelAから「モデル変更」メッセージを発行できます。 ViewModelBインスタンスはこのメッセージを購読し、それぞれがAがメッセージを公開したときに通知を受けます。その後、ViewModelBはApproriate PropertyChangedイベントを発生させて、UIに何が変更されたかを伝えることができます。

あなたは

関連する問題