首先要说的是我在
WPF和MVVM模式的最开始.
在尝试一些自定义命令时,我想知道如何使用ICommand接口中的CanExecute Methode.
在我的例子中,我有一个SaveCommand,我只能在对象可以保存时启用.我的保存按钮的XAML代码如下所示:
- <Button Content="Save" Command="{Binding SaveCommand,Mode=TwoWay}" />
这是我的保存类的代码:
- 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();
- }
- }
- public ICommand SaveCommand
- {
- get
- {
- saveCommand = new Save(this);
- return saveCommand;
- }
- set
- {
- saveCommand = value;
- }
- }
这个结构不起作用.当isSaveable为true时,该按钮不会启用其自身.
解决方法
不要定义自己的ICommand实现,而是使用
RelayCommand
.
在下面的示例代码中,当用户在TextBox中键入内容时,将启用保存按钮.
XAML:
- <Window x:Class="RelayCommandDemo.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <StackPanel HorizontalAlignment="Center">
- <TextBox Text="{Binding Name,UpdateSourceTrigger=PropertyChanged}" Margin="5" Width="120"/>
- <Button Content="Save" Command="{Binding SaveCommand}" Margin="3"/>
- </StackPanel>
- </Window>
代码背后:
- 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<bool> canExecuteEvaluator;
- public RelayCommand(Action methodToExecute,Func<bool> 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();
- }
- }
- }