WPF命令與MVVM模式:打造優雅的應用程序架構

?? 打造優雅的應用程序架構

    • 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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82642.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82642.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82642.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

真實案例拆解:智能AI客服系統中的兩類緩存協同

真實案例拆解:智能客服系統中的兩類緩存協同 在AI客服系統中,“響應速度”與“語義準確性”是一對天然的矛盾體。為了實現秒級應答與智能理解的雙重目標,系統需要在技術架構中融合精確命中的緩存系統(如Redis)與模糊語義識別的向量數據庫(如Milvus)。這兩種能力的結合,…

FastAPI與MongoDB分片集群:異步數據路由與聚合優化

title: FastAPI與MongoDB分片集群:異步數據路由與聚合優化 date: 2025/05/26 16:04:31 updated: 2025/05/26 16:04:31 author: cmdragon excerpt: FastAPI與MongoDB分片集群集成實戰探討了分片集群的核心概念、Motor驅動配置技巧、分片數據路由策略、聚合管道高級應用、分片…

一起學數據結構和算法(三)| 字符串(線性結構)

字符串&#xff08;String&#xff09; 字符串是由字符組成的有限序列&#xff0c;在計算機中通常以字符數組形式存儲&#xff0c;支持拼接、查找、替換等操作。 簡介 字符串是計算機科學中最常用的數據類型之一&#xff0c;由一系列字符組成的有限序列。在大多數編程語言中&…

2025電工杯數學建模競賽A題 光伏電站發電功率日前預測問題 保姆級教程講解|模型講解

完整內容請看文章最下面的推廣群 2025電工杯數學建模競賽 A題保姆級分析完整思路代碼數據教學 2025電工杯 A題保姆級教程思路分析 DS數模-全國大學生電工數學建模&#xff08;電工杯&#xff09; A題保姆級教程思路分析 A題&#xff1a;光伏電站發電功率日前預測問題 下面我…

React Native 拼音及拼音首字母搜索組件開發

寫在前面 “用戶說找不到聯系人&#xff1f;拼音搜索功能必須安排上&#xff01;” —— 當產品經理第N次提出這個需求時&#xff0c;我意識到需要開發一個強大的拼音搜索組件。本文將詳細介紹如何開發一個支持拼音匹配、首字母搜索的React Native搜索組件&#xff0c;讓你的應…

springboot--實戰--大事件--用戶接口開發

開發模式&環境搭建 開發模式&#xff1a; 前后端分離開發 前端程序員寫前端頁面&#xff0c;后端程序員寫后端的接口&#xff0c;前端工程發送請求來訪問后臺&#xff0c;后臺處理完請求后要給前端相應對應的數據。 還需要一套標準來約束即接口文檔&#xff0c;在接口文…

html使用JS實現賬號密碼登錄的簡單案例

目錄 案例需求 思路 錯誤案例及問題 修改思路 案例提供 所需要的組件 <input>標簽&#xff0c;<button>標簽&#xff0c;<script>標簽 詳情使用參考&#xff1a;HTML 教程 | 菜鳥教程 案例需求 編寫一個程序&#xff0c;最多允許用戶嘗試登錄 3 次。…

小米玄戒O1架構深度解析(一):十核異構設計與緩存層次詳解

前言 這兩天&#xff0c;小米的全新SOC玄戒O1橫空出世&#xff0c;引發了科技數碼圈的一次小地震&#xff0c;那么小米的這顆所謂的自研SOC&#xff0c;內部究竟有著什么不為人知的秘密呢&#xff1f;我們一起一探究竟。 目錄 前言1 架構總覽1.1 基本構成1.2 SLC缺席的原因探…

VSCode如何像Pycharm一樣“““回車快速生成函數注釋文檔?如何設置文檔的樣式?autoDocstring如何設置自定義模板?

文章目錄 ?? 介紹 ???? 演示環境 ???? 讓VSCode擁有PyCharm級注釋生成能力 ???? 實現方案??? 備用方案?? 自定義注釋文檔格式樣式 ???? 切換主流注釋風格? 深度自定義模板??? 類型提示與注釋聯動優化?? 相關鏈接 ???? 介紹 ?? 用PyCharm寫P…

數據庫的事務(Transaction)

在數據庫中&#xff0c;事務&#xff08;Transaction&#xff09; 是保證數據操作一致性和完整性的核心機制。它通過一組原子性的操作單元&#xff0c;確保所有操作要么全部成功&#xff08;提交&#xff09;&#xff0c;要么全部失敗&#xff08;回滾&#xff09;。以下是數據…

2025-05-27 Python深度學習7——損失函數和反向傳播

文章目錄 1 損失函數1.1 L1Loss1.2 MSELoss1.3 CrossEntropyLoss 2 反向傳播 本文環境&#xff1a; Pycharm 2025.1Python 3.12.9Pytorch 2.6.0cu124 1 損失函數 ? 損失函數 (loss function) 是將隨機事件或其有關隨機變量的取值映射為非負實數以表示該隨機事件的"風險&…

python+tkinter實現GUI界面調用即夢AI文生圖片API接口

背景 目前字節跳動公司提供了即夢AI的接口免費試用&#xff0c;但是并發量只有1&#xff0c;不過足夠我們使用了。我這里想做個使用pythontkinter實現的GUI可視化界面客戶端&#xff0c;這樣就不用每次都登錄官方網站去進行文生圖片&#xff0c;當然文生視頻&#xff0c;或者圖…

#git 儲藏庫意外被清空 Error: bad index – Fatal: index file corrupt

問題&#xff1a;通常是由于 Git 的索引文件損壞導致 原因&#xff1a;系統崩潰或斷電、硬盤故障、Git 操作錯誤等 方案&#xff1a;重建索引文件&#xff1a;將當前的索引文件重命名為其他名稱或刪除&#xff0c;比如 index.m&#xff0c;然后命令行重建索引&#xff0c;git…

GitLab 18.0 正式發布,15.0 將不再受技術支持,須升級【二】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

車載網關策略 --- 車載網關通信故障處理機制深度解析

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 鈍感力的“鈍”,不是木訥、遲鈍,而是直面困境的韌勁和耐力,是面對外界噪音的通透淡然。 生活中有兩種人,一種人格外在意別人的眼光;另一種人無論…

Unity數字人開發筆記

開源工程地址&#xff1a;https://github.com/zhangliwei7758/unity-AI-Chat-Toolkit 先致敬zhangliwei7758&#xff0c;開放這個源碼 一、建立工程 建立Unity工程&#xff08;UnityAiChat&#xff09;拖入Unity-AI-Chat-Toolkit.unitypackage打開chatSample工程&#xff0c;可…

Cherry Studio連接配置MCP服務器

之前寫了一篇關于Cherry Studio的文章&#xff0c;不了解的可以先看一下 AI工具——Cherry Studio&#xff0c;搭建滿血DeepSeek R1的AI對話客戶端【硅基流動DeepSeek API】-CSDN博客 最近Cherry Studio更新了一個新功能&#xff1a;MCP服務器 在 v1.2.9 版本中&#xff0c;…

OpenSSH 服務配置與會話保活完全指南

一、/etc/ssh/sshd_config 配置機制 1. 配置文件基礎 文件作用 OpenSSH 服務器 (sshd) 的主配置文件&#xff0c;控制連接、認證、端口轉發等行為。 加載與生效 修改后需重啟服務&#xff1a;sudo systemctl restart sshd # Systemd 系統 sudo service ssh restart # S…

阿里云國際版注冊郵箱格式詳解

“為什么我的阿里云國際版注冊總提示郵箱無效&#xff1f;” 這是許多初次接觸阿里云國際版&#xff08;Alibaba Cloud International&#xff09;的用戶常遇到的困惑。隨著全球化進程加速&#xff0c;越來越多的企業選擇阿里云國際版部署海外業務&#xff0c;而注冊環節中郵箱…

【IDEA問題】springboot本地啟動應用報錯:程序包不存在;找不到符號

問題&#xff1a; springboot本地啟動應用報錯&#xff1a; 程序包xxx不存在&#xff1b;找不到符號 解決方案&#xff1a; 1.確保用maven重新導入依賴 2.刪除.idea文件夾 3.invalidate caches里&#xff0c;把能選擇的都勾選上&#xff0c;然后清除緩存重啟 4.再在上方工具欄…