🎮 打造优雅的应用程序架构
- 1. 🧩 命令系统基础
- 1.1 🤔 为什么需要命令?
- 1.2 🏗️ ICommand接口
- 1.3 🛠️ 实现基本命令
- 2. 🏛️ MVVM模式详解
- 2.1 🧱 MVVM三大组件
- 2.2 🏗️ 创建ViewModel基类
- 2.3 🎯 典型ViewModel示例
- 3. 🧩 命令绑定实战
- 3.1 🎨 View中的命令绑定
- 3.2 🎭 带参数的命令
- 4. 🚀 MVVM进阶技巧
- 4.1 🧩 消息传递
- 4.2 🏗️ 依赖注入
- 5. 🧪 测试与调试
- 5.1 🧪 单元测试ViewModel
- 5.2 🐞 常见问题解决
- 6. 🏆 实战:完整的CRUD应用
- 6.1 📦 数据服务层
- 6.2 🏗️ 完整ViewModel
- 7. 🚀 总结与进阶
1. 🧩 命令系统基础
1.1 🤔 为什么需要命令?
在传统事件处理模型中,我们这样处理按钮点击:
private void Button_Click(object sender, RoutedEventArgs e)
{// 处理点击逻辑
}
这种模式存在几个问题:
- 🚫 业务逻辑与UI代码混杂
- 🔌 难以实现启用/禁用状态管理
- 🔄 复用性差
命令系统解决了这些问题!
1.2 🏗️ ICommand接口
WPF命令系统基于ICommand接口:
public interface ICommand
{event EventHandler CanExecuteChanged;bool CanExecute(object parameter);void Execute(object parameter);
}
1.3 🛠️ 实现基本命令
创建一个简单的命令类:
/// <summary>
/// 实现ICommand接口的RelayCommand类,用于将UI操作(如按钮点击)绑定到ViewModel中的方法
/// </summary>
public class RelayCommand : ICommand
{// 私有字段,存储要执行的委托private readonly Action _execute;// 私有字段,存储判断命令是否可以执行的委托(可选)private readonly Func<bool> _canExecute;/// <summary>/// 构造函数/// </summary>/// <param name="execute">要执行的委托方法</param>/// <param name="canExecute">判断命令是否可以执行的委托方法(可选)</param>/// <exception cref="ArgumentNullException">当execute参数为null时抛出</exception>public RelayCommand(Action execute, Func<bool> canExecute = null){// 检查execute参数是否为null,如果是则抛出异常_execute = execute ?? throw new ArgumentNullException(nameof(execute));// 可选地设置canExecute委托_canExecute = canExecute;}/// <summary>/// 当命令的可执行状态可能已更改时触发的事件/// </summary>public event EventHandler CanExecuteChanged;/// <summary>/// 确定此命令是否可以在其当前状态下执行/// </summary>/// <param name="parameter">命令使用的数据(此实现中未使用)</param>/// <returns>如果此命令可以执行,则为true;否则为false</returns>public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;/// <summary>/// 执行命令/// </summary>/// <param name="parameter">命令使用的数据(此实现中未使用)</param>public void Execute(object parameter) => _execute();/// <summary>/// 引发CanExecuteChanged事件,通知命令的可执行状态可能已更改/// </summary>public void RaiseCanExecuteChanged(){// 使用空事件参数触发CanExecuteChanged事件CanExecuteChanged?.Invoke(this, EventArgs.Empty);}
}
2. 🏛️ MVVM模式详解
2.1 🧱 MVVM三大组件
组件 | 职责 | 示例 |
---|---|---|
🎨 View | 用户界面展示 | MainWindow.xaml |
📦 ViewModel | 业务逻辑和状态 | MainViewModel.cs |
🗃️ Model | 数据模型和业务规则 | Product.cs |
2.2 🏗️ 创建ViewModel基类
public abstract class ViewModelBase : INotifyPropertyChanged
{public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null){if (EqualityComparer<T>.Default.Equals(field, value)) return false;field = value;OnPropertyChanged(propertyName);return true;}
}
2.3 🎯 典型ViewModel示例
public class ProductViewModel : ViewModelBase
{private string _searchText;private ObservableCollection<Product> _products;public string SearchText{get => _searchText;set{if (SetField(ref _searchText, value)){SearchCommand.RaiseCanExecuteChanged();}}}public ObservableCollection<Prod