首先要说的是我在
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(); } } }