WPF MVVM框架 - Prism DelegateCommand 命令绑定
在 WPF 的 Prism 框架中,DelegateCommand 是实现 ICommand 接口的核心组件,专门用于 MVVM 模式中的命令绑定。
它的主要功能是将 UI 操作(如按钮点击)与 ViewModel 中的逻辑解耦,同时支持条件执行(例如控制按钮是否可点击)。
核心功能
委托绑定
通过委托(Delegate)定义命令的实际操作(Execute)和是否允许执行的判断逻辑(CanExecute)
public DelegateCommand ClickCommand { get; private set; }
// 构造函数中初始化
public MyViewModel()
{
ClickCommand = new DelegateCommand(OnClick, CanClick);
}
private void OnClick()
=> MessageBox.Show("Command executed!");
private bool CanClick()
=> IsButtonEnabled; // 返回 true/false 控制按钮状态参数传递
支持泛型 DelegateCommand<T> 传递参数(例如从 UI 元素获取输入)
public DelegateCommand<string> SubmitCommand { get; private set; }
public MyViewModel()
{
SubmitCommand = new DelegateCommand<string>(OnSubmit, CanSubmit);
}
private void OnSubmit(string parameter)
=> MessageBox.Show($"Input: {parameter}");
private bool CanSubmit(string parameter)
=> !string.IsNullOrEmpty(parameter);动态状态更新
通过 RaiseCanExecuteChanged() 手动触发 CanExecute 重新验证,更新 UI 控件的启用状态
private bool _isEnabled;
public bool IsEnabled
{
get => _isEnabled;
set
{
_isEnabled = value;
ClickCommand.RaiseCanExecuteChanged(); // 通知 UI 更新按钮状态
}
}使用场景
按钮点击
将按钮的 Command 属性绑定到 ViewModel 的 DelegateCommand:
<Button Content="Click Me" Command="{Binding ClickCommand}" />条件性操作
根据业务逻辑动态控制命令是否可用(例如表单验证通过后才允许提交):
private bool CanSubmit(string input)
=> input?.Length > 5;优势
解耦 UI 与逻辑:View 仅负责触发命令,具体逻辑由 ViewModel 处理。
可测试性:命令逻辑可通过单元测试直接验证,无需依赖 UI 自动化。
灵活性:支持同步/异步操作(结合 async/await 和 DelegateCommand 封装)。
注意事项
内存泄漏:确保命令在不需要时解除订阅(通常 Prism 已处理内部逻辑)。
UI 线程:若在非 UI 线程更新状态,需通过 Dispatcher 调用 RaiseCanExecuteChanged。
完整示例
ViewModel
public class MainViewModel : BindableBase
{
private string _inputText;
public string InputText
{
get => _inputText;
set => SetProperty(ref _inputText, value, () => SubmitCommand.RaiseCanExecuteChanged());
}
public DelegateCommand SubmitCommand { get; }
public MainViewModel()
{
SubmitCommand = new DelegateCommand(Submit, CanSubmit);
}
private void Submit()
=> MessageBox.Show($"Submitted: {InputText}");
private bool CanSubmit()
=> !string.IsNullOrEmpty(InputText);
}View
<StackPanel>
<TextBox Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Submit" Command="{Binding SubmitCommand}" />
</StackPanel>