MVVM模式的3种command总结[2]--RelayCommand

RelayCommand本来是WPF下面用的一种自定义的command,主要是它用到了事件管理函数,这个SL下面是没有的。不过这部分代码如果修改一下,也可以在SL下面使用,和WPF下面的实现思路差不多。

先看下RelayCommand的定义,一共有2种。

复制代码
 1     public class RelayCommand<T> : ICommand
 2     {
 3         public RelayCommand(Action<T> execute)
 4             : this(execute, null)
 5         {
 6         }
 7 
 8         public RelayCommand(Action<T> execute, Predicate<T> canExecute)
 9         {
10             if (execute == null)
11                 throw new ArgumentNullException("execute");
12 
13             _execute = execute;
14             _canExecute = canExecute;
15         }
16 
17         [DebuggerStepThrough]
18         public bool CanExecute(object parameter)
19         {
20             return _canExecute == null ? true : _canExecute((T)parameter);
21         }
22         public event EventHandler CanExecuteChanged
23         {
24             add{}
25             remove{} 
26             //add
27             //{
28             //    if (_canExecute != null)
29             //        CommandManager.RequerySuggested += value;
30             //}
31             //remove
32             //{
33             //    if (_canExecute != null)
34             //        CommandManager.RequerySuggested -= value;
35             //}
36         }
37 
38         public void Execute(object parameter)
39         {
40             _execute((T)parameter);
41         }
42 
43         readonly Action<T> _execute = null;
44         readonly Predicate<T> _canExecute = null;
45 
46         bool ICommand.CanExecute(object parameter)
47         {
48             throw new NotImplementedException();
49         }
50 
51         event EventHandler ICommand.CanExecuteChanged
52         {
53             add { throw new NotImplementedException(); }
54             remove { throw new NotImplementedException(); }
55         }
56 
57         void ICommand.Execute(object parameter)
58         {
59             throw new NotImplementedException();
60         }
61     }
复制代码

第一种是采用泛型的Relaycommand定义,这个泛型到底用在哪里还暂时没看明白。

复制代码
 1  public class RelayCommand : ICommand
 2     {
 3         public RelayCommand(Action execute)
 4             : this(execute, null)
 5         {
 6         }
 7 
 8         public RelayCommand(Action execute, Func<bool> canExecute)
 9         {
10             if (execute == null)
11                 throw new ArgumentNullException("execute");
12 
13             _execute = execute;
14             _canExecute = canExecute;
15         }
16 
17         [DebuggerStepThrough]
18         public bool CanExecute(object parameter)
19         {
20             return _canExecute == null ? true : _canExecute();
21         }
22         public event EventHandler CanExecuteChanged
23         {   //这里把实现注释掉了,这样在SL下面也可以用。
24             add { }
25             remove { }
26             //add
27             //{
28             //    if (_canExecute != null)
29             //        CommandManager.RequerySuggested += value;
30             //}
31             //remove
32             //{
33             //    if (_canExecute != null)
34             //        CommandManager.RequerySuggested -= value;
35             //}
36         }
37 
38         public void Execute(object parameter)
39         {
40             _execute();
41         }
42 
43         readonly Action _execute;
44         readonly Func<bool> _canExecute;
45     }
复制代码


第二种就是最常用的定义,可以看到在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!");
        }
复制代码


是不是和delegatecommand很类似?其实就差不多一样的,基本上就是变个类名而已。不过2个类看到的地方不一样,而且前端绑定的方法不同,所以就还是写一下。下一篇就看看解决思路完全不同的attachbehavior模式。

原文地址:https://www.cnblogs.com/changbaishan/p/3590600.html