Why use a RelayCommand or DelegateCommand instead of just implementing ICommand?
我只是了解WPF中的MVVM,对于WPF和MVVM都是全新的(我了解它是如何工作的,但从未使用过...)
我在网上找到的每个教程/文章都使用RelayCommand或DelegateCommand。
在我看来,这些模式使VM违反了SRP原则,因为它会将命令逻辑保存在其中。
为什么不只使用ICommand接口的自定义实现? 像这样:
假设您要显示一个人并将其保存到数据库中:
我的Xaml是这样的:
1 2 3 4 5 6 7 8 9 10 11 | <StackPanel> <TextBlock Width="248" Height="24" Text="The name is::" /> <TextBlock Width="248" Height="24" Text="{Binding Name}"> </TextBlock> <TextBox HorizontalAlignment="Left" Name="textBox1" Width="120" Height="23" VerticalAlignment="Top" Text="{Binding Name}" /> <Button Name="Salvar" VerticalAlignment="Bottom" Command="{Binding SavePerson}" CommandParameter="{Binding}">Save</Button> </StackPanel> |
这是我的VM:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | public class PersonVM: INotifyPropertyChanged { private string nameValue; public string Name { get{ return nameValue; } set { if (value != this.nameValue) { this.nameValue= value; NotifyPropertyChanged("Name"); } } } public ICommand SavePerson{ get { return new SavePersonCommand(); } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } #endregion } |
这是我的命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class SavePersonCommand: ICommand { #region ICommand Members public bool CanExecute(object parameter) { return (parameter as PersonVM) != null; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { PersonVM person = parameter as PersonVM; if(person != null) //Actually Save the person... } #endregion } |
我的方法有什么问题?
没什么...但是,如果您有一个真正特定于您的ViewModel的特定命令,而又不想将其公开给其他人,则DelegateCommand很有用,因为它实际上仅适用于您的ViewModel。 我也喜欢DelegateCommands,因为它们不需要您在ViewModel中传递的另一个类,因此编写的代码更少。 如果您提供的ViewModel是一个基本ViewModel,并且可以共享您的Command,则该方法很有用,该ViewModel被大量共享。
如果您不使用某些基本命令(框架的命令或您自己的自定义命令的命令),则会发现自己一次又一次地编写相同的代码。 例如:您不会在自己的命令中引发