查了不少資料,大概理清楚的就是有3種。當然類名可以自己取了,不過為了便於記憶和區分,還是和看到的文章里面用一樣的類名。
1.DelegateCommand
2.RelayCommand
3.AttachbehaviorCommand
因為MVVM模式適合於WPF和SL,所以這3種模式中也有一些小差異,比如RelayCommand下面的CommandManager方法就是WPF下面的,SL下面無法使用,不過我認為這3種方法中的基本思路都如出一轍,都是出自那位外國牛人的文章里面。主要的區別在於和VIEW中的控件的綁定使用上。有點不同的attachbehaviorcommand是prism4里面的一種設計模式,這個區別有點大。但我自己覺得最方便的還是這個DelegateCommand。
1 /// <summary> 2 /// Delegatecommand,這種WPF.SL都可以用,VIEW里面直接使用INTERACTION的trigger激發。比較靠譜,適合不同的UIElement控件 3 /// </summary> 4 public class DelegateCommand : ICommand 5 { 6 Func<object, bool> canExecute; 7 Action<object> executeAction; 8 bool canExecuteCache; 9 10 public DelegateCommand(Action<object> executeAction, Func<object, bool> canExecute) 11 { 12 this.executeAction = executeAction; 13 this.canExecute = canExecute; 14 } 15 16 #region ICommand Members 17 18 public bool CanExecute(object parameter) 19 { 20 bool temp = canExecute(parameter); 21 22 if (canExecuteCache != temp) 23 { 24 canExecuteCache = temp; 25 if (CanExecuteChanged != null) 26 { 27 CanExecuteChanged(this, new EventArgs()); 28 } 29 } 30 31 return canExecuteCache; 32 } 33 34 public event EventHandler CanExecuteChanged; 35 36 public void Execute(object parameter) 37 { 38 executeAction(parameter); 39 } 40 41 #endregion 42 }
這個類大概可以這樣來理解,構造函數中的action和func,action負責判斷是否執行這個command,action就是觸發這個command之后要執行的方法。這樣理解最淺顯,但對剛熟悉command的我來講,這樣最方便記憶和學習,為了使用ICommand接口實現的方法和事件的解釋搜搜就可以找到,但是剛開始理解起來還是有點晦澀。
下面是VM里面用這個command的例子。綁定了一個button控件,最簡單例子。cm1Click就是構造函數里面的fuc,負責執行響應事件的方法。Cancm1Click就是構造函數里面的action,負責判斷這個Command的響應事件是否執行,這里沒有用到判斷式,直接賦了一個true.
1 public class TestViewModels:INotifyPropertyChanged 2 { 3 public TestViewModels() 4 { 5 ...... 6 cm1click = new DelegateCommand(cm1Click,Cancm1Click); //初始化delegatecommand 7 8 } 9 .... 10 11 //DelegateCommand 12 13 #region command1 14 15 public ICommand cm1click { get; set; } 16 public void cm1Click(object param) 17 { 18 MessageBox.Show("CM1 clicked!"); 19 } 20 21 private bool Cancm1Click(object param) 22 { 23 return true; 24 } 25 26 #endregion command1 27 ...... 28 }
在XAML里面,用interaction來綁定這個事件,而不是在button里面用command來綁定,這樣做有個好處,就是非常直觀,並且可以響應其他的很多事件
<Button x:Name="BTN_CM1" Content="DelegateCommand" Height="115" Width="148" > <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{Binding cm1click}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>
如果是其他控件如grid等,要響應selectionchanged事件之類的,就可以直接在trigger里面把EventName修改下就可以了。在blend里面更方便,可以直接選擇。但是有個問題一直沒搞明白.這樣的話,怎么獲取事件的參數,我這里有個例子,再看看了再更新下。
