2011-05-26 48 views
6

在MVVM的各種教程中經常指出,MVVM的目標不是消除代碼隱藏,並且在代碼隱藏中仍然需要一些事件處理。事件而不是MVVM中的命令?

什麼是你需要編寫代碼隱藏事件,而不是在視圖模型使用命令的情況下?

回答

6

通常,如果您的代碼屬於UI邏輯,請將其保留在視圖的XAML或代碼隱藏中。視圖模型僅負責在視圖和模型之間橋接和綁定數據。

可以在我的一個問題How do I make a WPF window movable by dragging the extended window frame?中找到一個例子我使用的其中一個事件是SourceInitialized,其中我訪問Window的窗口句柄以執行一些Windows API魔術。但是,所有這些都與窗口有關,並且與窗口之外的應用程序邏輯無關,所以我將其全部限制在窗口的代碼隱藏文件中,使得視圖模型完全不知道它。

+0

請注意我的問題(以及我自己的答案)對MVVM絕對沒有提及;除了WPF和MVVM並不完全是同義詞這一事實之外,它還對其中的代碼範圍進行了很多說明。 – BoltClock 2011-05-26 12:12:42

5

在我看來,在MVVM,當事件涉及到的用戶界面,像動畫,可以在代碼隱藏文件編寫。

所有的業務邏輯都應該在視圖模型中。

3

我認爲有後臺使用代碼的自定義用戶控件的可能性。

假設您創建一個繼承TabItem的Closable Tab Item類。您可以使用事件處理該關閉操作並將其綁定到DP。

這當然是通用的,可以多次使用。

所以我想後面的代碼是可以接受的,當事件具有與UI,而不是數據模型或其他活動來實現。

5

根據我的經驗,使用不支持MVVM綁定的第三方控件將導致在代碼後面編寫代碼。即使對簡單的用法也是如此,例如選擇當前項目,閱讀當前選定的項目等,這些應該在控制中實現相當簡單但沒有。

這方面的一個示例是Silverlight的TreeView控件,而不是被的DependencyProperty(是可綁定的),這是一個普通的屬性,所以你不能結合的SelectedItem屬性。

而且作爲@BoltClock提到的,有時它似乎是合乎邏輯把一些代碼在代碼隱藏其真正涉及到什麼樣的觀點呢,並沒有任何與邏輯「的背後」的觀點。最好將這些邏輯放在代碼隱藏中。

3

我碰到的一個場景是第三方控件。一些像telerik grid這樣的第三方控件在內部使用自己的自定義數據類型來表示網格行等,並且您需要處理各種網格事件以將這些特定於UI的類型轉換爲您的custion類型,然後將它們傳遞給VM。

2

我會說任何「邏輯」,將需要是不同的,如果你被移植到另一個桌面UI(例如,MAC)應該在後面的代碼。 (例如,具有大致相同邏輯UI需求的其他平臺)

因此,當使用「懸停」在輸入字段上時,掛鉤所有要分離的事件應位於代碼後面,但決定在「狀態行「當用戶做懸停時應該在視圖模型中。

+0

當您針對.NET框架時,這有什麼關係?如果框架在mac,linux等支持,那麼WPF調用也將被支持。除非有部分支持的特定功能(沒有遵循單聲道,所以我不知道)。 – 2011-05-26 11:53:37

+0

@Josh,它可以幫助您思考什麼是應用程序UI邏輯的一部分,什麼是「外觀和感覺」。 – 2011-05-26 12:20:29

+1

你是說「外觀和感覺」屬於用戶界面,用戶界面邏輯可以放在虛擬機中?我感覺合理。 – 2011-05-27 13:10:24

4

你總是會碰到純粹主義者,認爲在代碼隱藏文件中永遠不應該有任何代碼。我通常是純粹主義者,但不是在這種情況下。

如果您具有非常特定於視圖的邏輯,它應該放在代碼隱藏文件中。當我編寫複雜的視圖時,需要根據視圖模型中的屬性或更改對視覺樹的結構進行大的更改,我將這些代碼放在視圖中。視圖模型不應該知道視圖的任何內容,因此它不能(也不應該)直接控制這些變化。有時候,這些更改可以通過Style或DataTemplate中的觸發器來實現,但有時老式代碼是最好的方式。

0

我沒有找到一個很好的方式來處理綁定列表框中的多個項目的選擇,並且必須在代碼後面執行它。但它不是「不乾淨」

+1

您可以實現多個列表框項的選擇,而無需代碼隱藏。它乾淨,工作很棒。你可以參考以下鏈接http://grokys.blogspot.com/2010/07/mvvm-and-multiple-selection-part-iii.html – 2011-05-31 09:54:13

+0

@Hasan,謝謝!正是我所需要的。如果遇到雙向綁定多選的問題,我認爲這會好得多! – Karel 2011-06-01 12:56:55