Command是事件的进化体,Wpf中可以将Command绑定到控件上,减少重复的事件代码。它的方便在于可以直接在ui进行操作,并在逻辑中使命令不可用。
微软为wpf内置了不少默认命令,诸如paste、copy、save等。下面的代码演示了一个简单的记事本程序。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height= " 30 "></RowDefinition>
<RowDefinition Height= " * "></RowDefinition>
</Grid.RowDefinitions>
<Menu Grid.Column= " 0 ">
<MenuItem Command= " Save " x:Name= " menuSave " Header= " Save "></MenuItem>
</Menu>
<TextBox x:Name= " tbx " Grid.Row= " 1 "></TextBox>
</Grid>
<Window.CommandBindings>
<CommandBinding Command= " Save " CanExecute= " CommandBinding_CanExecute " Executed= " CommandBinding_Executed " ></CommandBinding>
<Grid.RowDefinitions>
<RowDefinition Height= " 30 "></RowDefinition>
<RowDefinition Height= " * "></RowDefinition>
</Grid.RowDefinitions>
<Menu Grid.Column= " 0 ">
<MenuItem Command= " Save " x:Name= " menuSave " Header= " Save "></MenuItem>
</Menu>
<TextBox x:Name= " tbx " Grid.Row= " 1 "></TextBox>
</Grid>
<Window.CommandBindings>
<CommandBinding Command= " Save " CanExecute= " CommandBinding_CanExecute " Executed= " CommandBinding_Executed " ></CommandBinding>
</Window.CommandBindings>
在后台,实现了CanExecute和Executed的方法。
private
void CommandBinding_CanExecute(
object sender, CanExecuteRoutedEventArgs e)
{
if ( tbx.Text != "")
{
e.CanExecute = true;
}
else
{
e.CanExecute = false;
}
}
private void CommandBinding_Executed( object sender, ExecutedRoutedEventArgs e)
{
// 保存文件对话框
SaveFileDialog save = new SaveFileDialog();
save.Filter = " 文本文件|*.txt|所有文件|*.* ";
bool? result = save.ShowDialog();
if (result.Value)
{
// 执行保存文件操作
}
{
if ( tbx.Text != "")
{
e.CanExecute = true;
}
else
{
e.CanExecute = false;
}
}
private void CommandBinding_Executed( object sender, ExecutedRoutedEventArgs e)
{
// 保存文件对话框
SaveFileDialog save = new SaveFileDialog();
save.Filter = " 文本文件|*.txt|所有文件|*.* ";
bool? result = save.ShowDialog();
if (result.Value)
{
// 执行保存文件操作
}
}
但是内置的毕竟比较少,我们可以继承ICommand接口来自定义Command,在ICmmand中,包含CanExecute和Executed成员,我们在DelegateCommand类中实现他们。
public
class DelegateCommand<T> : ICommand
{
private readonly Action<T> executeAction;
private readonly Func<T, bool> canExecuteAction;
public event EventHandler CanExecuteChanged;
public DelegateCommand(Action<T> executeAction)
: this(executeAction, null)
{
}
public DelegateCommand(Action<T> executeAction,
Func<T, bool> canExecuteAction)
{
this.executeAction = executeAction;
this.canExecuteAction = canExecuteAction;
}
public bool CanExecute( object parameter)
{
return canExecuteAction== null ? true:canExecuteAction((T)parameter);
}
public void Execute( object parameter)
{
if (CanExecute(parameter))
{
executeAction((T)parameter);
}
}
{
private readonly Action<T> executeAction;
private readonly Func<T, bool> canExecuteAction;
public event EventHandler CanExecuteChanged;
public DelegateCommand(Action<T> executeAction)
: this(executeAction, null)
{
}
public DelegateCommand(Action<T> executeAction,
Func<T, bool> canExecuteAction)
{
this.executeAction = executeAction;
this.canExecuteAction = canExecuteAction;
}
public bool CanExecute( object parameter)
{
return canExecuteAction== null ? true:canExecuteAction((T)parameter);
}
public void Execute( object parameter)
{
if (CanExecute(parameter))
{
executeAction((T)parameter);
}
}
}
我们可以很方便地将command绑定到ui元素上,实现ui与逻辑的分离。
源码下载:/Files/shen6041/Command.zip