在WPF应用程序开发中,经常需要将多个命令组合在一起执行。本文将介绍一种实现命令组的方法,以及如何在实际应用中使用它。
在WPF应用程序中,可能会遇到这样的问题:当用户编辑了一个文本框(TextBox)并点击工具栏(ToolBar)上的保存按钮时,由于文本框没有失去焦点,绑定的数据没有被更新到业务对象中。这就需要在点击保存按钮之前,手动更新数据绑定。为了解决这个问题,设计了命令组(CommandGroup)类。
命令组类(CommandGroup)实现了WPF的ICommand接口,它的作用是将一组命令组合在一起,作为一个原子单位来执行。这个设计类似于之前创建的ValueConverterGroup类。
命令组的实现相对简单。它将所有的CanExecute和Execute方法调用委托给它的子命令。以下是命令组的代码实现:
private ObservableCollection<ICommand> _commands;
public ObservableCollection<ICommand> Commands
{
get
{
if (_commands == null)
{
_commands = new ObservableCollection<ICommand>();
_commands.CollectionChanged += this.OnCommandsCollectionChanged;
}
return _commands;
}
}
void OnCommandsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
this.OnCanExecuteChanged();
if (e.NewItems != null && e.NewItems.Count > 0)
{
foreach (ICommand cmd in e.NewItems)
{
cmd.CanExecuteChanged += this.OnChildCommandCanExecuteChanged;
}
}
if (e.OldItems != null && e.OldItems.Count > 0)
{
foreach (ICommand cmd in e.OldItems)
{
cmd.CanExecuteChanged -= this.OnChildCommandCanExecuteChanged;
}
}
}
void OnChildCommandCanExecuteChanged(object sender, EventArgs e)
{
this.OnCanExecuteChanged();
}
public bool CanExecute(object parameter)
{
foreach (ICommand cmd in this.Commands)
{
if (!cmd.CanExecute(parameter))
return false;
}
return true;
}
public event EventHandler CanExecuteChanged;
protected virtual void OnCanExecuteChanged()
{
if (this.CanExecuteChanged != null)
this.CanExecuteChanged(this, EventArgs.Empty);
}
public void Execute(object parameter)
{
foreach (ICommand cmd in this.Commands)
{
cmd.Execute(parameter);
}
}
在上述代码中,命令组类是一个命令容器。如果它的任何一个子命令的CanExecute方法返回false,命令组也会返回false。当被告知执行时,命令组会依次执行它的每一个子命令。
在示例应用程序中,可以看到工具栏上有一个保存按钮,以及两个文本框控件。这些文本框绑定到一个Foo对象,该对象具有Name和Age属性。编辑其中一个文本框后,点击保存按钮,会弹出一个消息框,显示Foo对象的当前值。