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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM