2008-11-19 58 views
17

我剛開始研究用於WPF應用程序的M-V-VM。除了這個特殊問題,一切都很有意義...M-V-VM設計問題。從ViewModel調用視圖

我有一個ViewModel我會打電話給Search。此ViewModel綁定到數據網格並列出項目的結果。現在,我有一個命令,需要調出另一個視圖,該項目的詳細信息。

把邏輯在搜索視圖中顯示另一個視圖看起來不正確,它根本不是可測試的。

這裏是我的視圖模型的實現,這是不可測試...

public class SearchViewModel 
{ 
    public void SelectItem() 
    { 
    // I want to call the DetailsView from here 
    // this seems wrong, and is untestable 
    var detailsView = new DetailsView(); 
    detailsView.Show(); 
    } 
} 

哪裏顯示從視圖模型方法的視圖邏輯在此模式中去嗎?

回答

12

視圖不應該在UI層「下面」的任何位置實例化。虛擬機存在於該領域之下,因此這不是放置該邏輯的地方(正如您已經意識到的那樣)。

幾乎總是會有一些UI級別的事件表明需要創建視圖。在您的示例中,它可能是數據網格上的一行(雙)單擊事件。這將是新的和顯示您的DetailsView窗口的地方。

+0

感謝您的幫助,這似乎是一個可行的解決方案。即使我不能單元測試設置視圖的邏輯(設置與注入的ViewModel交互的屬性),它仍會保留ViewModels可測試的地方,這是大多數邏輯所在。 – Jab 2008-11-21 16:47:40

+1

如果一個簡單的事件打開視圖,這是很好的。但是如果事件需要更多的操作,數據讀取和驗證呢?你也會把這些東西放進視圖嗎?或者創造另一個間接的層面? – Sam 2009-01-08 09:51:42

0

我們在這種模式上使用了一個變體,這裏我們有代表VM的控制器,所以View的datacontext是VM,我們的DTO是VM/Controller的屬性。我們將其稱爲控制器,因爲我們將其用作控制點,並因此處理來自視圖的某些命令。這是(我認爲)我們將在哪裏實施諸如你的命令。

18

由於Kiff指出:

意見不應該被 「下面」 的UI層的任何地方實例化。虛擬機存在於該領域之下,因此這不是放置該邏輯的地方(正如您已經意識到的那樣)。

幾乎總是會有一些UI級別的事件 指示 需要創建視圖。在您的 示例中,它可能是數據網格上的一行(雙) 單擊事件。 將成爲您的DetailsView窗口的新功能和顯示 的地方。

你必須認識到M-V-VM與MVC或MVP等其他模式略有不同。 ViewModel對UI沒有直接的瞭解。打開另一個視圖是一個視圖特定的功能。視圖模型應該更少關心使用數據的視圖或視圖的數量。我很可能永遠不會通過命令打開視圖。

alt text http://blogs.msdn.com//johngossman/attachment/576163.ashx

4

這裏的經驗在這個基本規則。

  • 如果你正在處理中 您認爲本地操作,您可以從 視圖模型intiate。

  • 如果它是交叉視圖(如顯示搜索屏幕),則可以使用EventAggregator模式(事件服務)或注入一個您調用方法的應用程序控制器,然後顯示搜索。

1

Catel包括涉及使用IUIVisualizerService的方法。這個接口定義了一個UI控制器,它可以用ViewModel以模態或無模式形式顯示對話框。基本上,在父vm內部,您創建了應保留在新視圖後面的視圖模型,並且該服務找到相關聯的視圖模型(基於某種約定或註冊),然後顯示它。