2013-05-02 53 views
7

我有一個實現了INotifyPropertyChanged的模型,它可能會被後臺業務線程更新。其相關的ViewModel也實現了INotifyPropertyChanged。他們的View顯然綁定到ViewModel。此視圖可能會顯示在多個位置,我的目標是在模型更改時全部更新。如果模型實現INotifyPropertyChanged,ViewModel應如何爲PropertyChanged事件註冊/註銷?

我知道ViewModel應該註冊Model的PropertyChanged事件。但我不知道何時何地是這種註冊和註銷的最佳場所。特別是關於註銷,因爲我害怕在Model/VM上有數百個VM事件處理程序,不再顯示VM /視圖。

在此先感謝。

回答

4

您是否絕對有必要限制視圖不直接綁定到模型?

可以公開模型作爲虛擬機的屬性,然後讓你的視圖直接綁定到它,從而不具有VM從型號

訂閱INPC

類似:

public class MyViewModel: INotifyPropertyChanged { 
... 

private MyModel _model; 
public MyModel Model { 
    get { 
    return _model; 
    } 
    set { 
    if (value == _model) 
     return; 
    value = _model; 
    RaisePropertyChanged(() => Model); 
    } 
} 
... 

} 

,並在XAML(當MyViewModelDataContext):

<TextBlock Text="{Binding Model.ModelProperty}" /> 

更新:

也許這是一些幫助,爲進軍模型的PropertyChanged事件「弱」時尚

IWeakEventListener

使用中央事件分派一個WeakEventManager的的使處理程序偵聽器不垃圾收集(或手動清除),即使源對象生存期超出了偵聽器。

這是在

Josh Smith's PropertyObserver

這曾經應該有希望解決您需要明確取消註冊的問題?

+0

感謝您的回覆。 我認爲這是必要的。因爲我必須操縱模型的數據以便能夠容易和清潔地綁定。 – n0ne 2013-05-02 14:56:08

+0

操縱模型的數據在哪裏?在VM中?這也不是一個好的做法。如果需要,您應該操縱Model中的Model的數據,或者如果它只是View渲染的操作,它應該位於Converter中。 – Viv 2013-05-02 14:57:46

+0

是的,我的意思是一些視圖渲染的東西。渲染有點複雜,不僅僅是一個屬性到屬性的映射,我可以使用一個Converter。 – n0ne 2013-05-02 15:06:11

0

我已經解決了這個問題,通過在負載上模擬事件並在卸載時刪除它們,問題在於視圖模型可能會在事件離開屏幕時錯過事件。我通常只是在加載時快速刷新數據。

OnLoad - 從模型和掛鉤事件中刷新VM數據。 OnUnLoad - 刪除已經放置的鉤子。

+0

好主意!但是如果該項目在Unload屏幕之外呢?虛擬機將會錯過它,並且事件掛鉤會一直保持在那裏... – n0ne 2013-05-02 15:57:30

+0

卸載事件很可能會在物品離開屏幕時觸發,但即使它保持加載狀態,在某些時候卸載事件將不再被調用需要。 – Andy 2013-05-02 18:16:43

+0

@如果有東西在訂閱你的對象的事件(如INPC),它永遠不會收集垃圾 - 爲什麼不只是使用WeakEvents? – BrainSlugs83 2014-09-05 22:08:21