C# WPF MVVM模式[經典]案例

01

前言

??????? Caliburn.Micro(簡稱CM)一經推出便備受推崇,作為一款MVVM開發模式的經典框架,越來越多的受到wpf開發者的青睞.我們看一下官方的描述:Caliburn是一個為Xaml平臺設計的小型但功能強大的框架。Micro實現了各種UI模式,用于解決實際問題。突出顯示的模式包括MVVM(表示模型)、MVP和MVC。目前CM框架還不不停的開發和迭代中,目前最新版本4.0.212,推出于2022年8月27日,已經可以支持.NET7。

02


項目介紹

解決方案由四個項目組成:見下圖

12f290f5563a78d49790a7d72b5f8c1c.png

HelloWorld:框架的搭建、容器注入相關;

HelloWorld.Core;放置數據模型,即mvvm中的M;

HelloWorld.ViewModels:模型視圖,即VM;

HelloWorld.Views:V,即視圖.

項目基于.NET5開發:

fec91cd0db9e38dea82c179b36bdc5ee.png

CM框架版本:4.0.212;

運行結果顯示:

a8473961e6e6f7af630a19eaa80b61db.png

03


代碼展示和講解

① 首先是HelloWorld講解,這里啟動代碼:Startup.CS

public class Startup : BootstrapperBase{SimpleContainer _container;public Startup(){Initialize();}protected override void Configure(){_container = new SimpleContainer().Singleton<IWindowManager, WindowManager>().Singleton<IEventAggregator, EventAggregator>();foreach (var asm in SelectAssemblies()){foreach (var vm in asm.GetTypes()){if (vm.Name.EndsWith("VM")){_container.RegisterPerRequest(vm, null, vm);}}}var myRule = new TypeMappingConfiguration{ViewModelSuffix = "VM",ViewSuffixList = new() { "" }};ViewLocator.ConfigureTypeMappings(myRule);ViewModelLocator.ConfigureTypeMappings(myRule);}protected override void OnStartup(object sender, StartupEventArgs e){base.OnStartup(sender, e);DisplayRootViewForAsync<IndexVM>();}protected override IEnumerable<Assembly> SelectAssemblies(){return new List<Assembly>{Assembly.Load("HelloWorld"),Assembly.Load("HelloWorld.Views"),Assembly.Load("HelloWorld.ViewModels"),};}protected override object GetInstance(Type service, string key){return _container.GetInstance(service, key);}}

這里容器采用了CM自帶的SimpleContainer:

開始先把窗口管理器和事件聚合器注冊到了容器中:

_container = new SimpleContainer().Singleton<IWindowManager, WindowManager>().Singleton<IEventAggregator, EventAggregator>();

然后通過反射把下面三個程序集:

Assembly.Load("HelloWorld"),Assembly.Load("HelloWorld.Views"),Assembly.Load("HelloWorld.ViewModels"),

中vm結尾的視圖模型文件注冊到容器:

foreach (var asm in SelectAssemblies()){foreach (var vm in asm.GetTypes()){if (vm.Name.EndsWith("VM")){_container.RegisterPerRequest(vm, null, vm);}}}

接下來是自定義了一套CM的VM和V的匹配規則,默認情況,CM的匹配規則是視圖以View結尾,視圖模型以ViewModel結尾,這里的規則是VM以VM結尾,View只要前綴和Viewmodel的一致就可以:

var myRule = new TypeMappingConfiguration{ViewModelSuffix = "VM",ViewSuffixList = new() { "" }};ViewLocator.ConfigureTypeMappings(myRule);ViewModelLocator.ConfigureTypeMappings(myRule);

②HelloWorld.Views,這里放的是視圖,代碼很簡單,不展開了,比較新穎的用法是它通過load函數接在view的:

cal:Message.Attach="[Event Loaded]=[Loaded($view,$eventArgs)]"
public void Loaded(UserControl control, RoutedEventArgs @event){Debug.WriteLine(control);Debug.WriteLine(@event);}

③ HelloWorld.ViewModels,視圖模型:

LoginVM.cs這是登錄窗體的后臺邏輯:點擊登錄后發送背景線程異步事件更新進度條:

public async Task DoLogin(){await _eventAggregator.PublishOnBackgroundThreadAsync(new BusyMessage(true));await Task.Delay(1000);MessageBox.Show("Test Login Success");await _eventAggregator.PublishOnBackgroundThreadAsync(new BusyMessage(false));}

IndexVM.cs:繼承IHandle<BusyMessage>,

接收事件更新進度條:

public Task HandleAsync(BusyMessage message, CancellationToken cancellationToken){if (message.IsBusy){BarValue = 50;}else{BarValue = 0;}return Task.CompletedTask;}

通過ioc容器獲取VM:

?public LoginVM LoginVM { get; set; } = IoC.Get<LoginVM>();

public LoginVM LoginVM { get; set; } = IoC.Get<LoginVM>();public TableVM TableVM { get; set; } = IoC.Get<TableVM>();

TableVM.cs:

數據集合定義:? public ObservableCollection<Foo> Data { get; set; }

開線程更新集合數據:用 await Task.Delay(1000);演示一秒

Task.Run(async () =>{while (true){if (IsShow){_data.Add(new Foo{Id = Guid.NewGuid(),Name = "John" + new Random().Next(1, 100),School = "上海大學"});Data = new ObservableCollection<Foo>(_data);}await Task.Delay(1000);}});

?[AddINotifyPropertyChangedInterface]:來源于,可以自動通知界面數據更新。

049ca8ee3eb9606d15dfe5c80e3a374f.png

04


源碼下載及聲明

聲明:首先感謝群友提供源碼,需要和源碼提供者本人直面交流的可以通過郵箱:xingrui_zhuang@asiasymbol.com 聯系.

源碼百度網盤鏈接鏈接:https://pan.baidu.com/s/1BHkVEFWHwGQf6EwHpWCBKw
提取碼:6666
技術群:添加小編微信并備注進群小編微信:mm1552923   
公眾號:dotNet編程大全

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

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

相關文章

shell數組

定義數組[rootwy shell]# a(1 2 3 4)顯示數組[rootwy shell]# echo ${a[]}1 2 3 4[rootwy shell]# echo ${a[*]}1 2 3 4顯示數組中的某個元素[rootwy shell]# echo ${a[0]}1增加元素[rootwy shell]# a[4]9[rootwy shell]# echo ${a[*]}1 2 3 4 9修改元素值 [rootwy shell]# a[2…

java二級程序題兩個角度_兩個角度圖_【SCME大一】使用JAVA語言深入理解程序邏輯答案_學小易找答案...

【填空題】《蝶戀花 佇倚危樓風細細 》的作者( )。【簡答題】簡要概述問卷調查的整體設計?【填空題】父母在,( ),游必有方。【填空題】白居易與劉禹錫并稱“( )”。【填空題】白居易,字( )。【填空題】白居易,是唐代偉大的( )主義詩人。【單選題】《紅樓夢》最成功處在于塑造了…

LINUX中常用操作命令

LINUX中常用操作命令 引用&#xff1a;http://www.daniubiji.cn/archives/25 Linux簡介及Ubuntu安裝 常見指令系統管理命令打包壓縮相關命令關機/重啟機器Linux管道Linux軟件包管理vim使用用戶及用戶組管理文件權限管理Linux簡介及Ubuntu安裝 Linux&#xff0c;免費開源&#x…

Log4j編寫

來自: http://www.blogjava.net/zJun/archive/2006/06/28/55511.html Log4J的配置文件(Configuration File)就是用來設置記錄器的級別、存放器和布局的&#xff0c;它可接keyvalue格式的設置或xml格式的設置信息。通過配置&#xff0c;可以創建出Log4J的運行環境。1. 配置文件L…

C# 為什么高手喜歡用StartsWith而不是Substring進行字符串匹配?

字符串的截取匹配操作在開發中非常常見&#xff0c;比如下面這個示例&#xff1a;我要匹配查找出來字符串數組中以“abc”開頭的字符串并打印&#xff0c;我下面分別用了兩種方式實現&#xff0c;代碼如下&#xff1a;using System;namespace ConsoleApp23 {class Program{stat…

Nginx 服務器開啟status頁面檢測服務狀態

原文&#xff1a;http://www.cnblogs.com/hanyifeng/p/5830013.html 一、Nginx status monitor 和apache 中服務器狀態一樣。輸出的內容如&#xff1a; 第1列&#xff1a; 當前與http建立的連接數&#xff0c;包括等待的客戶端連接&#xff1a;2第2列&#xff1a;接受的客戶端連…

elif是不是java關鍵字_C# 中的#if、#elif、#else、#endif等條件編譯符號 (轉載)

這些是C#中的條件編譯符號。這些指令我在項目中遇到過&#xff0c;查過網絡&#xff0c;問過人(當然&#xff0c;既不認識大牛&#xff0c;也不認識小牛&#xff0c;所以沒什么收獲)。今天翻看一本資料&#xff0c;有提到這個方面的東西&#xff0c;所以寫下來和能看到這篇文章…

從零開始React項目架構(四)

前言 使用當前的webpack配置能不能打包構建項目呢&#xff1f;當然可以&#xff0c;但這不是我們想要的&#xff0c;所以&#xff0c;讓我們來看一看生產環境需要怎么配置webpack吧 開發 生產環境配置 在根目錄創建webpack.pro.config.jsconst path require(path) const webpa…

在OpenCloudOS 上安裝.NET 6

開源操作系統社區 OpenCloudOS 由騰訊與合作伙伴共同倡議發起&#xff0c;是完全中立、全面開放、安全穩定、高性能的操作系統及生態。OpenCloudOS 沉淀了多家廠商在軟件和開源生態的優勢&#xff0c;繼承了騰訊在操作系統和內核層面超過10年的技術積累&#xff0c;在云原生、穩…

Linux 命令詳解(二)awk 命令

AWK是一種處理文本文件的語言&#xff0c;是一個強大的文本分析工具。之所以叫AWK是因為其取了三位創始人 Alfred Aho&#xff0c;Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。 語法&#xff1a; awk [選項參數] script varvalue file(s) 或 awk [選項參數] …

linux下vtune使用

安裝&#xff1a;http://www.cnblogs.com/jiu0821/p/5943533.html 終端輸入amplxe-gui,打開vtune界面。 點擊new project&#xff0c;進入project properties界面。進行配置&#xff1a; target&#xff1a;target type選擇launch application&#xff0c;application選擇程序可…

java產生的數字發送到頁面_JAVA中數字證書的維護及生成方法

Java中的keytool.exe可以用來創建數字證書&#xff0c;所有的數字證書是以一條一條(采用別名區別)的形式存入證書庫的中&#xff0c;證書庫中的一條證書包含該條證書的私鑰&#xff0c;公鑰和對應的數字證書的信息。證書庫中的一條證書可以導出數字證書文件&#xff0c;數字證書…

數據庫 創建 / 查看/ 刪除

創建數據庫 語法&#xff1a;CREATE DATABASE [IF NOT EXISTS] db_name; 重復創建會報錯&#xff0c;所以可以加上if not exists 注意&#xff1a;SQL語句必須以分號結尾 查看有哪些數據庫&#xff1a;SHOW DATABASES; 刪除數據庫 語法:DROP DATABASE [IF EXISTS] dbname;如果…

IDEA破解 2017 IDEA license server 激活(可用)

進入ide主頁面&#xff0c;help-register-license server,然后輸入 http://idea.iteblog.com/key.PHP&#xff08;注意&#xff1a;php要小寫&#xff09;即可~ 轉載于:https://www.cnblogs.com/austinspark-jessylu/p/7232982.html

《ASP.NET Core 6框架揭秘》實例演示[20]:“數據保護”框架基于文件的密鑰存儲...

《數據加解密與哈希》演示了“數據保護”框架如何用來對數據進行加解密&#xff0c;而“數據保護”框架的核心是“密鑰管理”。數據保護框架以XML的形式來存儲密鑰&#xff0c;默認的IKeyManager實現類型為XmlKeyManager。接下來我們通過模擬代碼和實例演示的形式來介紹一下Xml…

使用msui的回到頂部的一個小問題

2019獨角獸企業重金招聘Python工程師標準>>> 回到頂部&#xff0c;一直沒反應。 zepto加了動畫后&#xff0c;依然如此。原生寫法&#xff0c;jquery寫法&#xff0c;仍然沒有反應。 排查了后&#xff0c;發現獲取的對象錯誤。手機端上&#xff0c;滾動到頂部&#…

口袋精靈加速版java_口袋妖怪TCG!口袋對決加速版教程(免ROOT)

原標題&#xff1a;口袋妖怪TCG&#xff01;口袋對決加速版教程(免ROOT)《口袋對決》是一款以口袋精靈對戰為核心玩法的集換式卡牌游戲&#xff0c;原汁原味的口袋畫風&#xff0c;豐富多彩的各系精靈&#xff0c;策略競技的屬性相克。在5分鐘一局的卡牌對戰中&#xff0c;你將…

C#發布程序添加其他程序文件

注&#xff1a;程序發布文件&#xff0c;默認只發布自身程序直接引用的相關文件(A程序)。 如果需要添加其他程序(不同的應用程序B)文件&#xff0c;操作方法如下&#xff1a; 第一步&#xff1a;將B程序文件復制到A程序 第二步&#xff1a;將B程序文件右鍵--》屬性做如下更改&a…

k8s 讀書筆記 - 初始化容器 Init Container

Init Container 概述Init Container&#xff08;Init 容器&#xff09; 是一種特殊容器&#xff0c;在 Pod 內的應用容器啟動之前運行&#xff0c;執行相關的初始化操作。Init 容器可以包括一些應用鏡像中不存在的 實用工具 和 安裝腳本 。每個 Pod 中可以包含一個或多個容器&a…

jsp 連接access數據庫

參考筆記&#xff1a;https://www.cnblogs.com/mthoutai/p/7278995.html