2009-05-29 67 views
3

我已經開始創建一個wpf mvvm應用程序。 ViewModel的一個重要組成部分是一系列ICommands,它們有一個鬆散耦合的方式允許視圖與視圖模型交互。MVVM ICommand alternative

我的問題是,爲什麼我不能直接綁定到一個方法?

我已經使用了Josh Smith的ICommand的RelayCommand實現,它允許你將一個delgates注入到一個ICommand對象中,但是真的有一些更簡單的方法來允許按鈕push來調用viewmodel中的一個方法嗎?

我是新來的MVVM,我相信我需要一些啓示

+1

您可以綁定到一個方法:

回答

7

不能直接綁定到一個方法,因爲Button(例如)不具有接受委託的屬性。相反,它有一個Command類型的屬性ICommand。 A RelayCommand(又名DelegateCommand)只是包裝代表的ICommand

我看不出有什麼技術原因,它不會是可能的觀點由標記擴展的方式綁定到視圖模型具體方法:

<Button Command="{ViewModelMethod SomeMethodName}"/> 

然而,這將是慢,會增加視圖和視圖模型之間的耦合。如果視圖僅知道類型爲ICommand的視圖模型上的屬性,那麼該命令的實現可能完全改變(或者方法可以被重命名)而不會意識到視圖。

+0

爲什麼它會變慢?它需要使用反射嗎?但我確實瞭解你提到的耦合問題。 – Jose 2009-06-04 18:13:28

+0

嗯,其實我不認爲這會慢很多,因爲綁定到viewmodel命令也使用反射。然而,這種方法有一個缺點:由於ViewModelCommand標記擴展不是綁定,所以當ViewModel改變時它不會被更新:它只會被評估一次(除非它掛鉤到DataContextChanged事件以重新評估,但那是另一回事。 ..) – 2009-06-06 15:14:09

+0

首先,我說「慢」,而不是「慢」。重要的區別。其次,我在談論解決方案和調用方法,而不是綁定本身。使用虛擬機創建的代理將比反思性地解析視圖中的方法更快。因此,除了所有其他的退步之外,從視角來看這樣做會更慢。 – 2009-06-06 17:11:25

6

我完全不同意。

調用的速度沒有意義:命令是用戶交互,他們從不需要速度。

關於耦合的論點也有缺陷。爲什麼{Binding MyProperty}不是耦合而是{ViewMethod MyMethod}?

將特製「命令」包裹在方法中的要求是愚蠢的。命令在封面下可能是有用的實現,但是我們已經在C#中使用了方法,並用大而笨重的代碼替換它們。

而關於MarkupExtension和Binding的東西,確實很難。但這是可以完成的。實際上,您可以看看CodePlex上的MethodCall項目: http://methodcallthing.codeplex.com/

您可以使用綁定爲該方法選擇「this」,並且可以使用綁定來獲取參數。所有這些都是實時的,即在命令被調用時計算。另一個附加功能是方法調用的推出結果,您也可以使用綁定(OneWayToSource)。

5

ICommand爲您提供了CanExecute,這是控制啓用所必需的。一個簡單的代表不會。 ICommand是要走的路。

3

顯然,微軟需要一個Command作爲一流的東西,可能是因爲他們覺得CanExecute對於大多數應用程序來說是必需的。我不同意,並認爲CanExecute應該是另一個DependencyProperty,你將綁定到你的視圖模型的屬性,但是,嘿,我知道什麼?

可能他們也認爲需要從控件的datacontext中分離一個命令的實現。然而,這對我來說似乎沒有必要,因爲邏輯應該接近正在運行的數據,這是OO的基本原則。

個人而言,我避免在MVVM中使用命令,因爲您必須創建它們來實現它們。我只是讓視圖的代碼隱藏事件直到視圖模型。