6.2 命令绑定与交互
核心概念
ICommand接口
- 定义:
System.Windows.Input.ICommand是WPF命令系统的核心接口 - 关键方法:
Execute(object parameter):执行命令逻辑CanExecute(object parameter):确定命令是否可执行CanExecuteChanged:通知命令状态变化的事件
常用实现方式
RoutedCommand
WPF内置的路由命令实现,适合UI层简单交互RelayCommand/DelegateCommand
MVVM模式下的典型实现方案:public class RelayCommand : ICommand { private readonly Action<object> _execute; private readonly Predicate<object> _canExecute; public RelayCommand(Action<object> execute, Predicate<object> canExecute = null) { _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true; public void Execute(object parameter) => _execute(parameter); public event EventHandler CanExecuteChanged { add => CommandManager.RequerySuggested += value; remove => CommandManager.RequerySuggested -= value; } }
实战应用
XAML中的命令绑定
<Button Content="保存"
Command="{Binding SaveCommand}"
CommandParameter="{Binding SelectedItem}"/>
ViewModel中的命令实现
public class DocumentViewModel : INotifyPropertyChanged
{
public ICommand SaveCommand { get; }
public DocumentViewModel()
{
SaveCommand = new RelayCommand(
execute: param => SaveDocument(param),
canExecute: param => IsDocumentValid
);
}
private void SaveDocument(object parameter)
{
// 保存逻辑实现
}
}
高级交互模式
复合命令
public class CompositeCommand : ICommand
{
private readonly List<ICommand> _commands = new List<ICommand>();
public void RegisterCommand(ICommand command)
=> _commands.Add(command);
public bool CanExecute(object parameter)
=> _commands.All(cmd => cmd.CanExecute(parameter));
public void Execute(object parameter)
{
foreach (var cmd in _commands)
{
cmd.Execute(parameter);
}
}
// 事件实现省略...
}
命令参数传递技巧
直接绑定对象属性
<Button Command="{Binding EditCommand}" CommandParameter="{Binding CurrentItem}"/>使用MultiBinding
<Button.Content> <MultiBinding Converter="{StaticResource ParamConverter}"> <Binding Path="UserName"/> <Binding Path="UserRole"/> </MultiBinding> </Button.Content>
最佳实践
命令与方法的区别
- 命令支持启用/禁用状态管理
- 命令可被多个UI元素共享
- 命令支持路由事件
性能优化建议
- 避免在CanExecute中执行复杂逻辑
- 对高频操作命令使用命令缓存
- 及时注销CanExecuteChanged事件处理器
调试技巧
CommandManager.AddCanExecuteHandler(this, (s, e) => Debug.WriteLine($"Command {e.Command} can execute: {e.CanExecute}"));
常见问题解决方案
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 命令不触发 | DataContext未正确设置 | 检查绑定路径和DataContext继承链 |
| CanExecute状态不更新 | 未触发RequerySuggested事件 | 调用CommandManager.InvalidateRequerySuggested() |
| 参数传递失败 | 参数类型不匹配 | 使用ValueConverter进行类型转换 |
