2017-01-03 50 views
2

我有一個獨立的ICommand實現。它修改實體的信息。作爲視圖的ViewModel的屬性,同一實體綁定到View來自ICommand的反饋

我想要實現的是,實體(因此ViewModel,因此 - 視圖)在執行該命令後用新信息更新。我瞭解它的方式,ICommand-s是單向街道。他們修改基礎數據,但不應該給出直接結果。

因此,我通過使用MVVMLight框架,在執行結束時通過從Command內發送Message來實現此目的。當接收到消息時(更新信息作爲消息的屬性傳遞),暴露實體的視圖模型也訂閱相同的消息並自我更新。

附加好處是其他視圖模型也可以訂閱並對同一事件作出反應。但是,這個實施的主幹是events。從我讀過的內容來看,事件的整個概念並不適合MVVM模式。還是跨VM通信可以這樣做?

實施例:

域模型

  • 用戶
    • First Name
    • Last Name
    • Full Name { get { return First Name + Last Name } }

視圖模型

  • 用戶視圖模式 - User Domain Model周圍包裹,但不存儲它的實例
    • string First Name
    • string Last Name
    • string Full Name(注:不知道它是如何計算出來的任何東西)
    • ICommand Change First Name
    • 方法MapFromDomainModel(UserDomainModel)。當查看模型收到UserDomainChanged消息時調用。

命令

  • Change First Name : ICommand
    • 更改在User Domain Model
    • First Name發送一個消息UserDomainChanged(UserDomainModel)

看出,在這個例子中,視圖模型不知道如何Full Name計算,並且不/不應該知道的是,當First Name改變時,Full Name也應該被改變。這就是爲什麼命令直接在域模型上工作並觸發消息。

而且,我可能會在窗口的其他意見,具有結合到同一個用戶的域模型視圖模型。通過訂閱相同的消息,他們可以獨立更新自己。

這是一個很好的方法嗎?有更好的嗎?

+0

我會說這種方法完全沒問題。除非您想要將視圖模型的引用添加到您的命令或在您的實體上實現INotifyPropertyChanged。 – Jehof

+0

我通常在我的命令中修改一些屬性,然後由於NotifyPropertyChanges和相應的綁定而更新視圖。這是否足夠,或者你有更復雜的情況? – heltonbiker

+0

@heltonbiker,所以你的命令是修改視圖模型,而不是底層數據模型?我執行的命令執行持續更改 - 針對域模型,並且由於執行的業務邏輯,視圖模型的其他屬性可能會在命令或視圖模型不知情的情況下更改。 –

回答

2

我的理解是,ICommand的-S是單行道。他們修改基礎數據,但不應該給出直接結果。

你是對的。 ICommand接口的Execute方法具有返回類型void,這意味着它不會將任何類型的值或結果返回給該命令的調用者。

或跨VM通信確定要做這樣?

是的。使用事件聚合器或信使在兩個對象之間進行通信和使用普通事件之間的巨大差異是耦合。當您訂閱普通活動時,您可以在發佈商與活動用戶之間建立緊密的聯繫。訂戶需要以強大的參考出版商能夠訂閱事件和發佈者要求通過事件處理程序委託的用戶一個參考,以便能夠發佈事件。這導致組件之間的緊密耦合,這又往往導致較少的可維護應用。

通過在發佈者和用戶之間引入一個事件聚合器,您可以刪除此緊密耦合。用戶觀察事件聚合器而不是發佈者,發佈者只知道事件聚合器而不瞭解訂閱者。如果您想要廣泛的圖片,請參考以下博文:https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/

這是一個很好的方法嗎?有更好的嗎?

是的。使用事件聚合器/信使以鬆散耦合的方式在組件之間進行通信通常是一種好方法。另一種選擇是使用共享服務。這只是一個以分離的方式爲多個組件提供功能的類。它應該實現一個接口,並且通常將其註冊爲IoC容器中的單例:https://social.msdn.microsoft.com/Forums/en-US/22907a0f-d805-4195-8272-7c284b72d2ee/example-of-using-shared-services-prism?forum=wpf

請注意,在此特定示例中,您可能也已將視圖模型的FirstName屬性綁定到視圖中的目標屬性,當你希望刷新視圖而不是調用命令時,引發了FullName屬性的PropertyChanged事件,但我想你有理由調用一個命令,然後使用事件聚合器或信使發佈消息給外部世界是完全沒問題的。