我有一個架構問題,以及我想要一個意見的可能解決方案。我習慣了WP7的MVVM體系結構(只要有可能,但不幸的是,有時sdk似乎走向相反的方向)。ViewModel事件註冊和ViewModel生命週期
WP7強制使用ViewFirst方法,我覺得這很適合(除了我們無法重寫視圖創建的部分,就像在Silverlight中,使構造函數注入成爲可能)。 我發現自己很有信心,因爲大部分視圖模型都遵循其視圖的lyfetime。所以viewmodel是在創建視圖時創建的(通過訪問ViewModelLocator),ViewModel是(或者應該)只能被其視圖引用,當視圖被銷燬時,它的ViewModel也應該被銷燬(它不是強制性的,而是它的方式我去除非常罕見的情況下,我創建一個singleton viewmodel)。
我的viewmodel可能需要註冊一些單例服務事件(我創建的phoneservice或singleton類)。我的意思是,它可能需要註冊一個類,該類的生命週期不是由視圖模型本身決定的。 這些事件對我的viewmodel保持了一個硬引用,並且即使視圖被刪除,我的viewmodel也仍然存在,不僅如此,我的viewmodel將繼續接收和處理這些事件。 WeakEvent模式可能是一種可能的解決方案,但對於爲每個事件創建事件管理器都是不可取的。在我看來,最好的解決方案並不存在,並且應該成爲弱事件註冊的關鍵詞。
我找到的解決方案是讓我的viewmodel知道NavigateTo和NavigateFrom,所以我可以從那裏註冊和取消註冊事件。我還可以添加一些邏輯(例如,我只能在註銷的情況下取消註冊),注意在NavigateTo和NavigateFrom中有高光邏輯。
另一種可能的方式(我還沒有測試過)可能會讓我的viewmodel意識到視圖定型並在視圖完成時執行一些清理,但我總是有這種感覺,因爲這種方法並不被推薦使用,定稿。此外,我不清楚性能會受到多大影響。
您如何看待viewmodel生命週期與其視圖相同(它總是簡化我的應用程序直到現在)? 您如何看待NavigateTo-Navigate從ViewModel感知解決方案? 您對View-Finalization ViewModel感知解決方案有什麼看法? 您是否遇到過這些或其他類型的解決方案?
問候 SkyG
UPDATE
我發現,最終確定的解決方案不會做的工作怎麼一回事,因爲它可以發生在未來的後期(也許永遠不會)。 現在看來我認爲最好的解決方案是viewmodelbase中的一對虛擬方法,用於初始化和清理視圖應該調用的事件註冊註銷。 可能會調用它們的時刻可能是在加載和卸載事件期間(當我不需要我的viewmodel處理事件時,如果我處於後續視圖中,在這種情況下,第一個視圖/ viewmodel仍然在後臺存活但如果它們的視圖被連接/分離到可視化樹上,則會加載/卸載)。
任何其他意見(甚至confermative)將不勝感激。
謝謝
我同意ViewModel不應該是viewaware,但我打算它不應該是特定的viewaware。我可以讓ViewModel知道導航而不知道視圖(例如使用Messenger)。有沒有其他技術上的原因,你不喜歡這種方法?對於清理它聽起來不錯,唯一的問題是什麼時候調用它,並且我只能想到在導航過程中調用它仍然與上面相同或在定稿期間,你有任何其他想法? – SkyG 2012-02-09 17:38:03
我也發現定稿不會奏效,因爲它可能會在未來發生。視圖模型庫中的虛擬清理是最好的解決方案(所以視圖只會瞭解基礎)。我必須弄清楚什麼時候是最好的時機。在大多數情況下,Unloaded事件可能是唯一的(記住,視圖從視覺樹中分離的所有時間都被稱爲視圖,但視圖可以在後臺堆棧中繼續存在)。在這種情況下,事件註冊應該在加載的事件中發生,所以我需要添加一個Initialize方法到viewmodel基礎。 – SkyG 2012-02-10 12:35:45