2011-07-06 50 views
4

好吧,我在一個綁定到ObservableCollection的XAML文件中有一個ItemsControl。 ObservableCollection可以在視圖模型類(我們稱之爲ViewModelA)上找到,而ObservableCollection中的每個項目都是的另一個視圖模型類(讓我們稱之爲類ViewModelB)。如何通知可觀察集合中某個項目的屬性已更改?

ViewModelA上有一個屬性,如果發生更改,間接將更改在ViewModelB類的許多實例中找到的屬性的值。換句話說,它不會直接訪問ViewModelB並設置其屬性,從而導致INotifyPropertyChange調用,而是下降到模型中,在我的模型中設置一些屬性,並且模型中的更改影響ViewModelB應該顯示的內容風景。

如何通知視圖ViewModelB中的某些內容已更改?

回答

2

你應該能夠告訴視圖集合已經改變,並反過來觸發它重新綁定到整個集合(這將更新視圖)。

如果您的模型實現了INotifyPropertyChanged,另一種選擇是讓您的ViewModelB類監聽它的包裝模型上的更改,並根據需要提出屬性更改的事件。

+0

+1;你的回答比問題更清楚,所以我會重申一般情況:通知更改視圖的兩種方法是「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的propertychanged掛鉤事件。根據我的理解,無論誰更改viewmodelB的屬性(模型類或其他任何人),並且如果屬性具有更改通知,視圖將自動更新。

1

理想情況下,您可以像Reed Copsey所指出的那樣執行...在模型上實現INotifyPropertyChanged並讓ViewModelB監聽這些事件。然後,無論更新發生在哪裏,ViewModelB都會收到更改。

但是,在某些情況下,模型不會(或不能)實現INotifyPropertyChanged。在這種情況下,您可能需要考慮使用事件聚合器模式在ViewModelA和ViewModelB實例之間傳遞消息。

在這種情況下,您可以從ViewModelA發佈「模型更改」消息。 ViewModelB實例將訂閱此消息,並且當A發佈消息時,每個實例都會收到通知。然後ViewModelB可以引發相應的PropertyChanged事件來告訴UI有什麼變化。

您可以在衆多的框架找到關於事件聚合更多的信息,包括

相關問題