一、MVVM模式介紹: 在網上看過很多的MVVM中各塊的介紹,感覺很混亂。找到如下的描述感覺很合理,也很好理解(https://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx)。 二、模式分析 在項目中使用這個模型,感覺有2點需要 ...
一、MVVM模式介紹:
在網上看過很多的MVVM中各塊的介紹,感覺很混亂。找到如下的描述感覺很合理,也很好理解(https://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx)。
二、模式分析
在項目中使用這個模型,感覺有2點需要理解透,不然項目運行中肯定得亂套。
- 如上圖描述的模塊的角色和職責。
上面描述的很清楚了,但是幾點地方總結下:
1)有些地方將Model看成是只有數據的對象,但是這裡顯然不是。
2)View 的Ui Logic指的是控制項自己的一些顯示邏輯,比如某些動畫。(不知道其他怎麼理解的,後續我們會把視窗的創建等都放在這裡)。
3)ViewModel的界面呈現邏輯有時候容易和Model的業務邏輯混在一起。
- 模塊之間的通信。
模塊通信包括View和ViewModel、ViewModel和ViewModel、ViewModel和Model之間的通信。
三、項目分析
1、需求:
1) 視窗統一管理,自動維護視窗及子視窗的生命周期。同時包括模態及非模態視窗。
2) 分離界面,界面邏輯,後臺呈現邏輯,不包括其他界面或模塊邏輯,界面職責明確獨立。
3) 界面生命周期檢測,業務邏輯處理與生命周期同步,即界面銷毀不響應界面邏輯處理。
4) 視窗業務邏輯之間的通信傳遞便利,降低通信的代碼成本。
5) 適應WPF的特性。比如binding,Command之類的。
2、分析
1)、父視窗與子視窗的生命周期同步
在wpf里,子視窗和父視窗設置ower關係存在如下問題:
父視窗關閉,方法內的模態視窗也會關閉。只要設置owner屬性。必須在父視窗關閉之前手動關閉,否則視窗會卡住。
父視窗關閉,非模態視窗也會一起關閉,只要設置owner屬性。任務欄問題,只顯示父視窗的。
所以需要自建視窗管理模塊管理子視窗的銷毀。
2)、MVVM模式分析
讓UI界面與邏輯能夠很好地分離又協同工作,調研MVVMLight,使用binging、Command和Messenger可以達到以上目標。
四、模型設計
通過以上的分析項目中使用的模型如下。
1、Window Manager
工廠化視窗的創建,視窗銷毀的反註銷,父子視窗的生命周期綁定,以及視窗的業務邏輯的反註冊。
2、View
MVVM模式中的第一個V,包括視窗及子視圖。所有的與界面元素有關的內容,請放在此處操作。
一般情況下,View和ViewModel是一一對應的,生命周期一致,因為如果ViewModel還能響應數據,但是視窗銷毀了,有可能產生異常或者讓人很難理解的地方。
3、ViewModel
MVVM模式中的VM。
4、Model
MVVM模式中的M,主要後臺業務模型。這個地方的模型有可能是線程只能的有通知能力的模塊(比如線程拉取服務消息通知界面展示)
5、View和ViewModel的通信
View和Viewmodel的數據通過binging;View的事件通過Command傳遞給Viewmodal;Viewmodal通過messenge通知事件到View,在View中WindowMessage創建View。
6、ViewModel和ViewModel的通信
通過messenge的方式需要在視窗關閉的時候反註冊。通過Window Manager統一來處理。
7、ViewModel和Model的通信
ViewModel可以直接Call Model的方法;Model和ViewModel通過代理方式(messenger)通信,需要在視窗關閉的時候反註冊。通過Window Manager統一來處理。
Model的通知消息(線程類的拉取消息)通知消息,如果有ViewModel註冊該消息會收到通知。
8、其他
l Messenger調查
Messenger.Default.Register<string>(this, "hahaClose", OnHHClose);
Messenger.Default.Unregister(this);
Messenger.Default.Send<string>("132123", "hahaClose");
如果沒有註冊就調用Send,不會出錯;
註冊的響應必須手動釋放,在視窗關閉的時候不會自動去掉這個關聯關係。
從以上可以看到,視窗間通信支持複雜的對象。