如何在WPF上使用ICommand的CanExecute方法
首先要说的是我在WPF和MVVM模式的最开始。
在尝试一些自定义命令时,我想知道如何使用ICommand接口中的CanExecute Methode。
在我的例子中,我有一个SaveCommand,我只能在对象可以保存时启用它。 我的保存按钮的XAML代码如下所示:
这是我的保存类的代码:
class Save : ICommand { public MainWindowViewModel viewModel { get; set; } public Save(MainWindowViewModel viewModel) { this.viewModel = viewModel; } public bool CanExecute(object parameter) { if (viewModel.IsSaveable == false) return false; return true; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { viewModel.Save(); } }
ViewModel中的save属性如下所示:
public ICommand SaveCommand { get { saveCommand = new Save(this); return saveCommand; } set { saveCommand = value; } }
这个结构不起作用。 当isSaveable为true时,该按钮不会启用它自己。
不要定义自己的ICommand
实现,而是使用RelayCommand
。
在下面的示例代码中,当用户在TextBox
键入内容时,将启用保存Button
。
XAML:
代码背后:
using System; using System.Windows; using System.Windows.Input; namespace RelayCommandDemo { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new VM(); } } public class VM { public String Name { get; set; } private ICommand _SaveCommand; public ICommand SaveCommand { get { return _SaveCommand; } } public VM() { _SaveCommand = new RelayCommand(SaveCommand_Execute, SaveCommand_CanExecute); } public void SaveCommand_Execute() { MessageBox.Show("Save Called"); } public bool SaveCommand_CanExecute() { if (string.IsNullOrEmpty(Name)) return false; else return true; } } public class RelayCommand : ICommand { public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } private Action methodToExecute; private Func canExecuteEvaluator; public RelayCommand(Action methodToExecute, Func canExecuteEvaluator) { this.methodToExecute = methodToExecute; this.canExecuteEvaluator = canExecuteEvaluator; } public RelayCommand(Action methodToExecute) : this(methodToExecute, null) { } public bool CanExecute(object parameter) { if (this.canExecuteEvaluator == null) { return true; } else { bool result = this.canExecuteEvaluator.Invoke(); return result; } } public void Execute(object parameter) { this.methodToExecute.Invoke(); } } }