【WPF】MVVM的消息機制

在WVM(Model-View-ViewModel)架構中,消息機制主要用于實現ViewModel與View之間的通信,同時保持它們的分離。這對于維護代碼的清晰度和可測試性非常重要。在WPF(Windows Presentation Foundation)應用程序中,有幾種常見的方法來實現MVVM中的消息傳遞機制。

1. 使用事件聚合(Event Aggregator)

事件聚合是一種設計模式,它允許發布者和訂閱者通過一個中介進行通信,而不需要直接相互引用。Prism庫提供了一個實現這個模式的EventAggregator類,它可以幫助你在ViewModel之間發送和接收消息。

  • 發布消息:創建一個繼承自PubSubEvent<T>的事件類,并使用EventAggregator的GetEvent<Event>()方法獲取該事件實例,然后調用Publish(T payload)方法發送消息。
  • 訂閱消息:同樣地,獲取事件實例后,可以使用Subscribe(Action<T> action, bool keepSubscriberReferenceAlive)方法訂閱該事件。

2. 使用Messenger或Mediator

Messenger是另一種實現松耦合消息傳遞的方法。MVVMLight Toolkit提供了一個Messenger類,支持不同類型的ViewModel之間傳遞消息。

  • 注冊消息:在接收方ViewModel中使用Messenger.Default.Register<T>(this, action)方法注冊特定類型的消息。
  • 發送消息:在發送方ViewModel中使用Messenger.Default.Send<T>(message)方法發送消息。

3. 使用命令(ICommand)

WPF提供了命令綁定機制,可以直接在View中綁定到ViewModel中的命令。這通常用于處理用戶界面觸發的動作,如按鈕點擊等。

  • 實現ICommand接口或使用RelayCommand(來自MVVMLight)等簡化命令的創建。
  • 在XAML中,使用Command屬性將UI元素(如Button)綁定到ViewModel中的命令。

4. 使用依賴屬性(Dependency Property)和綁定(Binding)

雖然這不是一種傳統意義上的“消息”機制,但通過綁定ViewModel的屬性到View上的控件,可以在數據變化時自動更新UI,反之亦然。這是MVVM的核心概念之一。

選擇合適的消息傳遞機制取決于具體的應用需求。對于需要解耦組件間交互的情況,事件聚合器或Messenger可能是更好的選擇;而對于直接響應用戶操作的場景,使用命令可能更加直接有效。

5.MVVMLight Toolkit示例

假設我們有兩個ViewModel:MainViewModelSecondViewModel。當用戶在MainView上點擊按鈕時,我們需要通知SecondViewModel更新其顯示的內容。

5.1. 添加MVVMLight Toolkit

首先,確保你的項目中包含了MVVMLight Toolkit。你可以通過NuGet包管理器安裝它:

Install-Package MvvmLightLibs

5.2. 創建Messenger消息類

創建一個簡單的類用于攜帶消息數據:

public class UpdateMessage
{public string NewContent { get; set; }
}

5.3. 在SecondViewModel中注冊接收消息

SecondViewModel中,注冊監聽特定類型的消息,并定義接收到消息后的操作:?

public class SecondViewModel : ViewModelBase
{public SecondViewModel(){Messenger.Default.Register<UpdateMessage>(this, (action) =>{// 更新屬性,觸發UI更新DisplayContent = action.NewContent;});}private string _displayContent;public string DisplayContent{get => _displayContent;set => Set(ref _displayContent, value);}
}

?5.4. 在MainViewModel中發送消息

MainViewModel中,當你想要通知SecondViewModel更新內容時,可以發送一個消息:

public class MainViewModel : ViewModelBase
{public ICommand SendMessageCommand { get; private set; }public MainViewModel(){SendMessageCommand = new RelayCommand(() =>{// 發送消息給SecondViewModelMessenger.Default.Send(new UpdateMessage { NewContent = "Hello from MainViewModel!" });});}
}

在這個例子中,當用戶觸發SendMessageCommand(例如通過點擊按鈕),MainViewModel會發送一條UpdateMessage消息。由于SecondViewModel已經注冊了這種類型的消息,它將會接收到這條消息并更新其DisplayContent屬性,進而更新相關的UI部分。

?

6.其他幾種方案

6.1. 使用Prism框架

Prism是一個強大的框架,專為構建松散耦合、可維護和可測試的XAML應用程序而設計。它提供了一個EventAggregator服務,可以用于發布和訂閱事件,從而實現在不同ViewModel或組件之間的通信。

  • 優點:支持模塊化開發,提供多種實用工具和服務。
  • 缺點:對于簡單的項目來說可能過于重量級。

6.2. 自定義消息傳遞系統

如果你不想引入額外的庫,可以創建自己的消息傳遞系統。這通常涉及到創建一個共享的消息中心,允許發送者發布消息,接收者則可以訂閱感興趣的消息類型。?然后在你的ViewModel中訂閱或發送消息。

public class MessageCenter
{public event EventHandler<string> OnMessageReceived;public void SendMessage(string message){OnMessageReceived?.Invoke(this, message);}
}

6.3. 使用依賴屬性和綁定

雖然這不是傳統意義上的消息機制,但是通過依賴屬性和數據綁定也可以達到類似的效果。例如,你可以將一個ViewModel中的屬性綁定到另一個ViewModel中,當屬性值發生變化時,UI也會自動更新。

6.4. 使用.NET內建的事件(Event)

直接在ViewModel中定義事件,并讓需要監聽這些事件的View或其他ViewModel進行訂閱。這是一種非常基礎的方法,適用于簡單的場景。然后在另一個ViewModel中訂閱此事件。

public class MainViewModel
{public event EventHandler<string> MessageSent;private void OnSendMessage(string message){MessageSent?.Invoke(this, message);}
}

每種方法都有其適用的場景和優缺點。選擇哪種方法取決于你的具體需求、項目的復雜度以及團隊對特定技術的熟悉程度。對于小型應用或者簡單的消息傳遞需求,自定義解決方案或.NET內建的事件可能就足夠了;而對于更復雜的場景,考慮使用Prism或MVVMLight這樣的框架可能會更加合適。

?

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

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

相關文章

以樓宇自控關鍵技術,夯實現代低碳建筑發展重要基礎

當“碳達峰、碳中和”成為全球發展共識&#xff0c;建筑行業作為能源消耗與碳排放的重要領域&#xff0c;正加速向低碳化轉型。在這場綠色變革中&#xff0c;樓宇自控技術憑借對建筑設備的智能管控與能源優化能力&#xff0c;成為現代低碳建筑建設的核心支撐。從數據采集到智能…

西電【信息與內容安全】課程期末復習筆記

西電【信息與內容安全】課程期末復習筆記 來自2022年春的古早遺留檔案&#xff0c;有人需要這個&#xff0c;我就再發一下吧。 ? 平時成績&#xff1a; 10%。線上&#xff1a; 10% &#xff08;線上學習內容&#xff0c; 共 100 分。&#xff09;實驗&#xff1a; 10% &#…

【論文閱讀筆記】ICLR 2025 | 解析Ref-Gaussian如何實現高質量可交互反射渲染

Reflective Gaussian Splatting Info 會議 【ICLR 2025】 作者 復旦大學&#xff0c;薩里大學&#xff1b;復旦張力教授團隊 Github地址 https://github.com/fudan-zvg/ref-gaussian.git Project地址 https://fudan-zvg.github.io/ref-gaussian/ Abstract 新視圖合成得益…

面向GPU、CPU及機器學習加速器的機器學習編譯器

機器學習編譯器概述 機器學習編譯器是一種專門針對機器學習工作負載設計的工具&#xff0c;旨在將高層模型描述&#xff08;如TensorFlow或PyTorch模型&#xff09;高效編譯為可在不同硬件&#xff08;如GPU、CPU或專用加速器&#xff09;上執行的底層代碼。其核心目標是優化計…

論文分類打榜賽Baseline(2):InternLM昇騰硬件微調實踐

本文來自社區投稿&#xff0c;作者丁一超 書生大模型實戰營第5期已正式啟動&#xff0c;本期實戰營新增「論文分類打榜賽」&#xff0c;以幫助學員更好地掌握大模型技能。 本文將手把手帶領大家如何基于昇騰微調 InternLM 模型&#xff0c;輕松上手論文自動分類任務。從環境配…

mac安裝mvnd結合idea

mac安裝mvnd結合idea hi&#xff0c;我是阿昌&#xff0c;今天記錄一下mac系統下如何安裝mvnd同時通過maven-helper插件配置mvnd命令&#xff0c;提升編譯速度&#xff1b; 0、前言 如果你正在開發一個由大量模塊組成的大型項目&#xff0c;Gradle可以讓大型項目構建的更快&…

擴展模塊--QWebEngine功能及架構解析

Qt WebEngine 模塊在 Qt 6.9 中提供了基于 Chromium 的網頁渲染引擎功能。 一、主要功能 核心功能 網頁渲染引擎 基于 Chromium 項目的最新穩定版本 支持現代 HTML5、CSS3 和 JavaScript 標準 主要組件 QWebEngineView - 用于顯示網頁內容的 widget QWebEnginePage - 表示…

Spring Boot Admin監控

1、概述 Spring Boot Admin 是一款用于監控 Spring Boot 應用程序的開源工具&#xff0c;可幫助開發者實時監控應用的運行狀態、性能指標、日志信息等。 2、核心功能 應用狀態監控 顯示應用是否在線、啟動時間、運行時長等基礎信息。監控 JVM 相關指標&#xff1a;內存使用情…

【QT】QTableView自定義樣式:僅顯示行間隔、隱藏列間隔、表頭樣式、表格樣式、單行選中等

目錄 0.背景 1.詳細代碼 0.背景 項目需要&#xff0c;我有一個自定義的類Steer_Electrode_Table&#xff0c;是一個QTableView&#xff1b; 記錄一下QTableView修改前后的樣式&#xff0c;僅供參考 看一下我修改前后的樣式對比 1.詳細代碼 void Steer_Electrode_Table::init…

mvnd-快速打包maven項目

mvnd 一、簡介一、定位與背景二、核心架構與加速原理三、使用注意事項 二、下載安裝三、idea集成mvnd插件四、打包測試時長 一、簡介 mvnd&#xff08;Maven Daemon&#xff09;是Apache Maven團隊推出的高性能構建工具&#xff0c;旨在解決傳統Maven構建速度慢的問題。它通過…

C++ 中的尾調用優化TCO:原理、實戰與匯編分析

C尾調用優化 什么是尾調用&#xff1f;描述無返回值函數最后調用函數也可能做尾調用優化 例子關鍵特征&#xff08;寫法&#xff09; 尾調用和尾遞歸的區別&#xff1f;為什么尾調用優化可以提高效率&#xff1f;通常的遞歸調用&#xff1a;尾調用優化&#xff1a;為什么棧幀復…

Java集合 - ArrayList底層源碼解析

下面開始對 Java 中 ArrayList 的深度源碼分析&#xff0c;基于 JDK 8 的實現&#xff08;后續版本略有差異&#xff0c;但核心邏輯一致&#xff09;。我們將從 類結構、擴容機制、核心方法實現、性能優化、線程安全問題 等角度進行詳細解析 一、類結構與核心字段 1. 類繼承關…

【Qt】Qt控件

文章目錄 Qt控件Layout Spacer垂直布局QVBoxLayout水平排列布局QHBoxLayout網格布局 QGridLayout表格布局 QFormLayout Button Contain命令按鈕Push Button工具按鈕Tool Button單選按鈕Radio Button復選框按鈕Check Box命令鏈接按鈕Command Link Button按鈕盒Button Box組合框G…

PHP基礎-運算符

PHP 的運算符是編程中非常基礎但又非常重要的一部分&#xff0c;掌握它們能讓你更靈活地處理各種邏輯、計算和流程控制。 算術運算符 用于基本數學運算&#xff1a; 運算符含義示例加法$a $b-減法$a - $b*乘法$a * $b/除法$a / $b%取模$a % $b 示例&#xff1a; <?ph…

AR珠寶佩戴與傳統的珠寶購物有哪些區別??

AR 珠寶佩戴與傳統的珠寶購物究竟存在著哪些顯著區別呢?在傳統的珠寶購物模式里&#xff0c;顧客往往需要花費時間和精力前往實體珠寶店。踏入店內&#xff0c;首先映入眼簾的便是那一排排的玻璃展柜&#xff0c;此時&#xff0c;銷售人員會熱情地走上前&#xff0c;小心翼翼地…

華為云CAE部署spring cloud服務

1 概述 華為云CAE&#xff08;Cloud Application Engine云應用引擎&#xff09;是一個面向WEB、微服務應用的Serverless托管服務&#xff0c;提供極速部署、極低成本、極簡運維的一站式應用托管方案。支持從源碼、軟件包、鏡像包快速發布應用&#xff0c;秒級彈性伸縮、按量付…

【技術工具】源碼管理 - GIT工具

【技術工具】源碼管理 - GIT工具 1 前言 之前參考語雀一位大佬的&#xff0c;但鏈接找不到了&#xff0c;僅供參考。 1、檢查空白錯誤 //確認將提交的內容中有無空白信息 git diff --check 2、嘗試讓每一個提交成為一個邏輯的獨立變更集 盡量使每筆提交都成為獨立的patch&a…

Objective-c Block 面試題

以下是對我們這整段關于 Objective-C 中 Block、__block 修飾符、內存管理行為、生命周期等內容的全面總結&#xff0c;并附帶了一套適合面試準備的面試題集&#xff08;帶答案&#xff09;。 &#x1f9e0; 一、知識總結&#xff1a;Objective-C Block __block 修飾符 ? Bl…

AndroidMJ-基礎-05

基礎part5: 9:測試相關 postman genemotion espresso 10:性能相關 profiler 9.測試相關 espresso相關&#xff1a; Android Espresso 自動化測試指南&#xff08;Java 版&#xff09;-CSDN博客 10.性能相關 profiler相關&#xff1a; AndroidStudio之內層泄漏工具Profiler…

R語言 | 如何使用R書寫html文檔?

更靈活的書寫方式&#xff0c;可以直接看3. 1. 可用函數 cat()函數writeLines()函數sink()函數重定向輸出到HTML文件 小結&#xff1a;cat()適合簡單HTML&#xff0c;writeLines()適合多行內容&#xff0c;sink()適合復雜場景。 說明&#xff1a;盡可能不用R包&#xff0c;減…