WPF中的命令的实现与参数传递

在MVVM中,有下面几种实现命令的方式

一、实现命令的常见方式:DelegateCommand(或RelayCommand)

public class DelegateCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;
    
    public event EventHandler CanExecuteChanged;
    
    public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    
    public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true;
    
    public void Execute(object parameter) => _execute(parameter);
    
    public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

// 在ViewModel中的使用
public class MainViewModel
{
    public ICommand SaveCommand { get; }
    public ICommand DeleteCommand { get; }
    
    public MainViewModel()
    {
        SaveCommand = new DelegateCommand(OnSave, CanSave);
        DeleteCommand = new DelegateCommand<Customer>(OnDelete, CanDelete);
    }
    
    private void OnSave(object parameter) { ... }
    private bool CanSave(object parameter) { ... }
    
    private void OnDelete(Customer customer) { ... }
    private bool CanDelete(Customer customer) { ... }
}

二、使用Microsoft的CommunityToolkit.Mvvm中的RelayCommand

using CommunityToolkit.Mvvm.Input;

public partial class MainViewModel
{
    [RelayCommand]
    private void Save()
    {
        // 无参数命令
    }
    
    [RelayCommand]
    private void Delete(Customer customer)
    {
        // 带参数命令
    }
    
    // 异步命令
    [RelayCommand]
    private async Task LoadDataAsync()
    {
        await Task.Delay(1000);
    }
}

三、使用Prism框架的DelegateCommand

using Prism.Commands;

public class MainViewModel
{
    public DelegateCommand SaveCommand { get; }
    public DelegateCommand<Customer> DeleteCommand { get; }
    
    public MainViewModel()
    {
        SaveCommand = new DelegateCommand(Save, CanSave);
        DeleteCommand = new DelegateCommand<Customer>(Delete, CanDelete);
    }
}
优缺点比较:

自定义DelegateCommand:灵活,但需要自己实现;适用于不想引入外部框架的项目。

CommunityToolkit.Mvvm:现代,代码简洁,支持异步命令和属性通知,推荐在新项目中使用。

Prism的DelegateCommand:功能强大,适用于使用Prism框架的大型项目。

带参数的命令示例(XAML中绑定):

xml
<!-- 按钮直接绑定到命令,CommandParameter可以是固定值或绑定 -->
<Button Content="Delete" 
        Command="{Binding DeleteCommand}" 
        CommandParameter="{Binding SelectedCustomer}" />

<!-- 列表项中每个项都有一个按钮,CommandParameter绑定到当前项 -->
<ListBox ItemsSource="{Binding Customers}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" />
                <Button Content="Delete" 
                        Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
                        CommandParameter="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
posted @ 2025-12-30 10:12  长松入霄汉远望不盈尺  阅读(2)  评论(0)    收藏  举报