欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > asp.net >内容正文

asp.net

【WPF】MVVM模式的3种command

发布时间:2025/4/16 asp.net 12 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【WPF】MVVM模式的3种command 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
原文:【WPF】MVVM模式的3种command

1.DelegateCommand

2.RelayCommand

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 Memberspublic 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 command1public 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" Height="115" Width="148" ><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定义

public class RelayCommand : ICommand{public RelayCommand(Action execute): this(execute, null){}public RelayCommand(Action execute, Func<bool> canExecute){if (execute == null)throw new ArgumentNullException("execute");_execute = execute;_canExecute = canExecute;}[DebuggerStepThrough]public bool CanExecute(object parameter){return _canExecute == null ? true : _canExecute();}public event EventHandler CanExecuteChanged{ //这里把实现注释掉了,这样在SL下面也可以用。add { }remove { }//add//{// if (_canExecute != null)// CommandManager.RequerySuggested += value;//}//remove//{// if (_canExecute != null)// CommandManager.RequerySuggested -= value;//}}public void Execute(object parameter){_execute();}readonly Action _execute;readonly Func<bool> _canExecute;}

第二种就是最常用的定义,可以看到在CanExecuteChanged事件里面把commmandmanager方法给注释掉了,就可以在SL下面使用这个类,而且现在看好像也没有什么问题。

在代码上看,Relaycommand和delegatcommand基本上没有啥区别,也是实现了func和action两个参数的办法,基本思路一样。

它们最大的区别就是在前端的调用方式上。delegatecommand使用了expression的SDK里面的interaction来绑定事件,而这种就是直接通过buttonbase的command属性来绑定,因此只能执行单击事件,所以使用范围比较局限,不过如果用interaction来绑定事件的话,其实实现就和delegatecommand一样了。不过为了总结下学习,还是分开来区别下。

前端XAML的代码

<Button x:Name="BTN_CM2" Content="Command2" Height="103" HorizontalAlignment="Left" Margin="115,123,0,0" VerticalAlignment="Top" Width="109" Command="{Binding command2}" />

后台

private ICommand _command2;public ICommand command2{get{if (this._command2 == null){this._command2 = new RelayCommand(() => this.cm2Click(),() => this.Cancm2Click);}return this._command2;}set { }}public bool Cancm2Click{get { return true; }}public void cm2Click(){MessageBox.Show("CM2 Clicked!");}

总结

以上是生活随笔为你收集整理的【WPF】MVVM模式的3种command的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。