在WPF开发中,ICommand 是实现命令模式的核心接口,尤其在 MVVM(Model-View-ViewModel) 架构中扮演着至关重要的角色。通过使用 RelayCommand(也称为 DelegateCommand),我们可以轻松地将用户界面操作(如按钮点击)与 ViewModel 中的逻辑解耦。本文将手把手教你如何在 C# 中实现一个完整的 RelayCommand,并将其应用于 WPF 项目中,即使是编程小白也能轻松上手!
ICommand 是 .NET 提供的一个接口,用于封装“可执行的操作”。它包含两个核心成员:
Execute(object parameter):定义命令执行时要运行的逻辑。CanExecute(object parameter):返回一个布尔值,表示当前命令是否可以执行(例如按钮是否启用)。WPF 内置了 RoutedCommand,但它依赖于 UI 元素,不适合 MVVM 模式。而 RelayCommand 是一个轻量级、灵活的自定义实现,允许我们将命令逻辑完全放在 ViewModel 中,实现真正的关注点分离。这也是 C#命令模式 在 WPF 中的最佳实践之一。
首先,我们创建一个通用的 RelayCommand 类,它实现了 ICommand 接口:
using System;using System.Windows.Input;public class RelayCommand : ICommand{ private readonly Action _execute; private readonly Func<bool>? _canExecute; public event EventHandler? CanExecuteChanged { add => CommandManager.RequerySuggested += value; remove => CommandManager.RequerySuggested -= value; } public RelayCommand(Action execute, Func<bool>? canExecute = null) { _execute = execute ?? throw new ArgumentNullException(nameof(execute)); _canExecute = canExecute; } public bool CanExecute(object? parameter) => _canExecute == null || _canExecute(); public void Execute(object? parameter) => _execute();} 这段代码的关键点:
Action 用于传入无参的执行方法;你也可以扩展支持带参数的版本(如 Action<object>)。CanExecuteChanged 事件通过订阅 CommandManager.RequerySuggested 自动触发 UI 刷新(例如按钮启用/禁用状态)。接下来,我们在 ViewModel 中定义命令:
using System.ComponentModel;using System.Runtime.CompilerServices;public class MainViewModel : INotifyPropertyChanged{ private string _message = "点击按钮试试看!"; public string Message { get => _message; set { _message = value; OnPropertyChanged(); } } public ICommand ClickCommand { get; } public MainViewModel() { ClickCommand = new RelayCommand( execute: () => Message = "你好,WPF MVVM!", canExecute: () => !string.IsNullOrEmpty(Message) ); } public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }} 最后,在 View(XAML)中将按钮的 Command 属性绑定到 ViewModel 的命令:
<Window x:Class="MyApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="RelayCommand 示例" Height="200" Width="300"> <Window.DataContext> <local:MainViewModel /> </Window.DataContext> <StackPanel Margin="20"> <TextBlock Text="{Binding Message}" FontSize="16" Margin="0,0,0,20"/> <Button Content="点击我" Command="{Binding ClickCommand}" FontSize="14" Padding="10"/> </StackPanel></Window> 通过以上步骤,你已经成功实现了 WPF 中的 RelayCommand,并完成了基本的 MVVM命令绑定。这种模式不仅让代码更清晰、可测试,还极大地提升了应用的可维护性。记住,掌握 WPF ICommand 和 C#命令模式 是成为 WPF 高级开发者的必经之路!
提示:你可以进一步扩展 RelayCommand 以支持泛型参数(如 RelayCommand<T>),从而处理更复杂的交互场景。