?? 打造優雅的應用程序架構
- 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