zoukankan      html  css  js  c++  java
  • 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模式。

  • 相关阅读:
    Jmeter-日期格式转换为时间戳
    Java中异常的处理
    Java中接口的新特性,为接口添加静态方法和默认方法
    Java接口的应用之代理模式
    Java之接口(interface)的理解
    JAVA中使用super调用属性、方法、构造器
    JAVA方法的重写
    Java之方法
    Java之匿名对象
    关于多态性的使用
  • 原文地址:https://www.cnblogs.com/matoo/p/2452987.html
Copyright © 2011-2022 走看看