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模式。

  • 相关阅读:
    Java实现 LeetCode 56 合并区间
    JQuery实现对html结点的操作(创建,添加,删除)
    JQuery实现对html结点的操作(创建,添加,删除)
    JQuery实现对html结点的操作(创建,添加,删除)
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 55 跳跃游戏
    Java实现 LeetCode 54 螺旋矩阵
    Java实现 LeetCode 54 螺旋矩阵
    Java实现 LeetCode 54 螺旋矩阵
  • 原文地址:https://www.cnblogs.com/matoo/p/2452987.html
Copyright © 2011-2022 走看看