3.AttachbehaviorCommand
因为MVVM模式适合于WPF和SL,所以这3种模式中也有一些小差异,好比RelayCommand下面的CommandManager要领就是WPF下面的,SL下面无法使用,不过我认为这3种要领中的根基思路都如出一辙,都是出自那位外国牛人的文章里面。主要的区别在于和VIEW中的控件的绑定使用上。有点差此外attachbehaviorcommand是prism4里面的一种设计模式,这个区别有点大。但我本身感受最便利的还是这个DelegateCommand。
DelegateCommand/// <summary> /// Delegatecommand,这种WPF.SL都可以用,VIEW里面直接使用INTERACTION的trigger激发。对照靠谱,适合差此外UIElement控件 /// </summary> public class DelegateCommand : ICommand { Func<object, bool> canExecute; Action<object> executeAction; bool canExecuteCache; public DelegateCommand(Action<object> executeAction, Func<object, bool> canExecute) { this.executeAction = executeAction; this.canExecute = canExecute; } #region ICommand Members public bool CanExecute(object parameter) { bool temp = canExecute(parameter); if (canExecuteCache != temp) { canExecuteCache = temp; if (CanExecuteChanged != null) { CanExecuteChanged(this, new EventArgs()); } } return canExecuteCache; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { executeAction(parameter); } #endregion }
这个类概略可以这样来理解,结构函数中的action和func,action卖力判断是否执行这个command,action就是触发这个command之后要执行的要领。这样理解最浅显,但对刚熟悉command的我来讲,这样最便利记忆和学习,为了使用ICommand接口实现的要领和事件的解释搜搜就可以找到,但是刚开始理解起来还是有点晦涩。
下面是VM里面用这个command的例子。绑定了一个button控件,最简单例子。cm1Click就是结构函数里面的fuc,卖力执行响应事件的要领。Cancm1Click就是结构函数里面的action,卖力判断这个Command的响应事件是否执行,这里没有用到判断式,直接赋了一个true.
public class TestViewModels:INotifyPropertyChanged { public TestViewModels() { ...... cm1click = new DelegateCommand(cm1Click,Cancm1Click); //初始化delegatecommand } .... //DelegateCommand #region command1 public ICommand cm1click { get; set; } public void cm1Click(object param) { MessageBox.Show("CM1 clicked!"); } private bool Cancm1Click(object param) { return true; } #endregion command1 ...... }
在XAML里面,用interaction来绑定这个事件,而不是在button里面用command来绑定,这样做有个好处,就长短常直不雅观,并且可以响应其他的很多事件
<Button x:Name="BTN_CM1" Content="DelegateCommand" > <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{Binding cm1click}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button>
RelayCommand
RelayCommand原来是WPF下面用的一种自界说的command,主要是它用到了事件打点函数,这个SL下面是没有的。不过这部分代码如果改削一下,也可以在SL下面使用,和WPF下面的实现思路差不久不多。
先看下RelayCommand的界说,一共有2种。
public class RelayCommand<T> : ICommand { public RelayCommand(Action<T> execute) : this(execute, null) { } public RelayCommand(Action<T> execute, Predicate<T> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } [DebuggerStepThrough] public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute((T)parameter); } public event EventHandler CanExecuteChanged { add{} remove{} //add //{ // if (_canExecute != null) // CommandManager.RequerySuggested += value; //} //remove //{ // if (_canExecute != null) // CommandManager.RequerySuggested -= value; //} } public void Execute(object parameter) { _execute((T)parameter); } readonly Action<T> _execute = null; readonly Predicate<T> _canExecute = null; bool ICommand.CanExecute(object parameter) { throw new NotImplementedException(); } event EventHandler ICommand.CanExecuteChanged { add { throw new NotImplementedException(); } remove { throw new NotImplementedException(); } } void ICommand.Execute(object parameter) { throw new NotImplementedException(); } }
第一种是给与泛型的Relaycommand界说