C# 值得永久收藏的WPF项目实战(经典)

01

简介

之前也写过好多篇CM框架相关的项目实战文章,比如:

C# WPF框架Caliburn.Micro快速搭建

C# WPF框架Caliburn.Micro入门实例1

C# WPF MVVM项目实战(进阶①)

C# WPF MVVM项目实战(进阶②)

C# WPF MVVM模式下在主窗体显示子窗体并获取结果

C# WPF Caliburn.Micro框架下利用Mef加载其它项目界面

C# WPF mvvm模式下combobox绑定(list<enum>、Dictionary<int,string>)

C# WPF MVVM模式Caliburn.Micro框架下事件发布与订阅

但是可能这些都是把一个综合性的项目分多个部分分别讲述的,有些初学者没有从前往后连续起来阅读的话,后面的部分可能就不容易理解了。其次,因为没有整体的构思,随着内容的增加,项目越来越显得笨重和凌乱,所以今天我重新搞了一个项目,希望以尽量少的代码,涵盖尽量多的知识点,帮助大家更好的理解和使用CM框架。

02


重要知识点

  • CM框架的配置和启动;

  • CM框架自带ioc容器SimpleContainer用法;

  • MVVM开发模式;

  • 事件聚合器EventAggregator进行事件发布和订阅;

  • 属性通知:

    ① CM框架下基类PropertyChangedBase用法;

    ②PropertyChanged.Fody.3.1.3下 [AddINotifyPropertyChangedInterface]用法;

  • 日志框架:Common.Logging和log4net用法;

  • CM框架下命名约定以及事件关联;

  • 用第三方库Xceed.Wpf.Toolkit.dll做等待窗体;

  • CM框架下Conductor用法;

  • CM框架下IWindowManager;

  • 双检锁单例模式用法;

  •  ListBox数据绑定以及窗体切换;

    如果以上知识点你都不敢兴趣或者已经熟知,那这篇文章不适合你,看到这里你就可以关闭网页了!

03


运行结果

d783b6457931876e46a6d58109f70d87.gif

04


项目说明

项目主要包括的类文件如下图:

db01b9e5b5b2615efa24e37938e34779.png

① MainWindowViewModel.cs类:

using PropertyChanged;
using System.Collections.ObjectModel;namespace Caliburn.Micro.Hello
{[AddINotifyPropertyChangedInterface]public class MainWindowViewModel : PropertyChangedBase, IViewModel{private static readonly Common.Logging.ILog logger = Common.Logging.LogManager.GetLogger<MainWindowViewModel>();public IViewModel ActiveWindowView { get; set; }public ObservableCollection<string> ListBoxItems { get; set; } public string SelectedItem { get; set; }public MainWindowViewModel(){logger.Info($"Enter [MainWindowViewModel].");ListBoxItems = new ObservableCollection<string>() { };ListBoxItems.Add("ShellView");ListBoxItems.Add("EventAggregatorView");ListBoxItems.Add("ConductorView");logger.Info($"Leave [MainWindowViewModel].");}public void ListBoxItems_SelectionChanged(){switch(SelectedItem){case "ShellView":ActiveWindowView = new ShellViewModel();break;case "EventAggregatorView":ActiveWindowView = EventAggregatorViewModel.Instance; break;case "ConductorView":ActiveWindowView = new ConductorViewModel(); break;default:break;}}}
}
  • [AddINotifyPropertyChangedInterface]:需要引用第三方库PropertyChanged.Fody,加上之后类里面的属性变更后会自动通知界面,无需再一个个单独触发;

  • logger是定义的common logging的一个通用日志,需要在nuget上引用:Common.Logging.Log4Net1213;

  • ListBoxItems_SelectionChanged()是listbox的选择改变事件:

    需要在前台附加事件:

    <ListBox Name="ListBoxItems" Grid.Column="0" SelectedItem="{Binding SelectedItem}" Margin="2"
    cal:Message.Attach="[Event SelectionChanged] = [Action ListBoxItems_SelectionChanged]"/>

ActiveWindowView 是我的主窗体,选择那个就激活那个

<ContentControl Name="ActiveWindowView"/>

②ShellViewModel.cs类:

从ioc容器获取一个IWindowManager并显示:

SimpleContainerViewModel simpleContainerViewModel = new SimpleContainerViewModel();IWindowManager windowManager = IoC.Get<IWindowManager>();windowManager.ShowDialog(simpleContainerViewModel);

CanSayHello和SayHello,只有CanSayHello条件满足才会执行SayHello

public bool CanSayHello{get { return !string.IsNullOrWhiteSpace(Name); }}public void SayHello(){  }

③EventAggregatorViewModel.cs

双检锁线程安全的单例模式:

private static EventAggregatorViewModel instance;private static object locker = new object();/// <summary>/// 双检锁/// </summary>public static EventAggregatorViewModel Instance{get{if (instance == null){lock(locker){if (instance == null){instance = new EventAggregatorViewModel();}}}return instance;}}

事件订阅:需要继承事件接口IHandle<PersonInfoEven>

private readonly IEventAggregator eventAggregator;this.eventAggregator = IoC.Get<IEventAggregator>(); this.eventAggregator.Subscribe(this);

事件处理方法:

public void Handle(PersonInfoEven message){PersonInfo = message.ToString();}

④SimpleContainerViewModel.cs

  方法1 同步ui发布事件

this.eventAggregator.PublishOnUIThread("i am a chinese");

 方法2 开线程去发布 

this.eventAggregator.Publish(new PersonInfoEven() {Name = "ZYR", Age = 18, Sex = "man" }, action =>{//方式①//Task.Factory.StartNew(action);//方式②Task.Run(action);});

等待窗体BusyIndicator ,需要引用第三方库Xceed.Wpf.Toolkit,

并添加名称空间:

xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"

<xctk:BusyIndicator Name="busyIndicator"  BusyContent="Publish Event ..." IsBusy="{Binding IsShow}" Style="{x:Null}">

⑤ConductorViewModel.cs:此类需要继承Conductor<object>

将需要激活的实例放到ActivateItem,就可以从界面绑定激活对应实例窗体

ActivateItem(new ShellViewModel());

05


源码下载

项目有点长,不可能每个细节都说得到位,能看到这里的都是真爱,那么下面给出源码百度网盘链接:

网盘链接:

https://pan.baidu.com/s/18LOVAIxy7WCWJisiPcOuAQ

提取码:添加小编微信获取

小编微信:mm1552923

公众号:dotNet编程大全

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/294026.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

InfoQ十周年:不忘初心,继续前行

我们都知道&#xff1a;软件正在改变世界&#xff0c;也已经看到了在加快这种变化时&#xff0c;于软件世界中我们的影响力。在这种热情下&#xff0c;10年前我们带着一些不寻常的信念与情怀创建了InfoQ&#xff1a;\\\\t我们相信&#xff1a;这个社区需要的内容是开发者所撰写…

eclipse_中的注释_快捷键

eclipse 中的注释 快捷键 把要注释的代码选中&#xff0c;按CtrlShift/ /* */ 形式的 ctrl/ //形式的 取消代码注释&#xff1a; 把要注释的代码选中&#xff0c;按CtrlShift\ /* */ 形式的 ctrl/ //形式的 (1)CtrlSpace 说明:内容助理。提供对方法,变量,参数,j…

html自动填充高度,html元素如何仅使用css填充剩余屏幕高度的100%?

html元素如何仅使用css填充剩余屏幕高度的100&#xff05;&#xff1f;我有一个标题元素和一个内容元素&#xff1a;#header#content我希望标题具有固定的高度&#xff0c;并且内容可以填满屏幕上可用的所有剩余高度&#xff0c;使用overflow-y: scroll;。这可能没有Javascript…

Android之bitmap压缩的几种方法的解读

转载&#xff1a;http://blog.csdn.net/chzphoenix/article/details/30242315?utm_sourcetuicool&utm_mediumreferral 最近在研究微信的sdk&#xff0c;在缩略图这遇到了一点问题。 微信的缩略图要求是不大于32k&#xff0c;这就需要对我的图片进行压缩。试了几种方法&a…

如何通过 C# kill 指定进程?

咨询区 robr我用代码动态的打开了一个 IE 进程&#xff0c;参考如下代码&#xff1a;static void Main(string[] args){ProcessStartInfo startInfo new ProcessStartInfo("iexplore.exe");startInfo.WindowStyle ProcessWindowStyle.Hidden;startInfo.Arguments …

[转]面向接口编程详解(一)——思想基础

我想&#xff0c;对于各位使用面向对象编程语言的程序员来说&#xff0c;“接口”这个名词一定不陌生&#xff0c;但是不知各位有没有这样的疑惑&#xff1a;接口有什么用途&#xff1f;它和抽象类有什么区别&#xff1f;能不能用抽象类代替接口呢&#xff1f;而且&#xff0c;…

bootstrap模态框

bootsrtap模态框不可叠加使用&#xff0c;点击提交时需要确认&#xff0c;暂时未解决转载于:https://www.cnblogs.com/witchgogogo/p/5550338.html

Oracle 在 多个Virtualbox 虚拟机间 跨不同物理宿主机进行通信

因为单位网络管理的原因&#xff0c;不太方便使用 Virtualbox 的Bridge Adapter 模式&#xff0c;故此欲采用NAT模式&#xff0c;不对外不暴露虚拟机IP。 但是此时会有一个问题&#xff1a;采用NAT模式后&#xff0c;在通常情况下&#xff0c; 从外面看&#xff0c;或者从物理机…

Android之解决在非Activity中使用startActivity

今天遇到一个问题就是&#xff0c;如何在非activity里面使用startActivity(); 解决办法如下、 需要我们有context intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent);

亚马逊 html代码转换,亚马逊七种产品描述常用HTML代码,文字颜色代码让Listing更出彩...

排版风格和排版水平对于亚马逊Listing的运营至关重要。虽说亚马逊以产品为王&#xff0c;但如果消费者打开的是一篇毫无美感的排版&#xff0c;视觉体验不舒服&#xff0c;获取不到吸引他的卖点&#xff0c;转化率将大大降低&#xff01;没使用HTML代码的卖家&#xff0c;产品描…

如何将自定义的 Delegate 转成 Func 委托?

咨询区 AndreyAkinshin场景是这样的&#xff0c;我自定义了一个 SomeDelegate 委托&#xff0c;然后将 Inc 方法灌入到其中&#xff0c;同时我也将 Inc 赋值给了 Func<int,int> 委托&#xff0c;参考代码如下&#xff1a;class Program{static void Main(string[] args){…

java 文件上传至oracle blob字段 实现

2019独角兽企业重金招聘Python工程师标准>>> 指定文件夹下的所有文件上传至oracle的blob字段&#xff0c;java实现 package com.huth;import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.FileInputStream; i…

基于DDD的.NET开发框架 - ABP工作单元(Unit of Work)

返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。 ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点&#xff0c;它旨在成为一个通用的WEB应用程序框架和项目模板。 ABP的官方网站&#xff1a;http://www.aspnetboilerp…

中国这门失传已久的武林绝学,竟让研究它的老外拿了诺贝尔奖

全世界只有3.14 % 的人关注了爆炸吧知识欲练神功学好物理中国武术&#xff0c;博大精深。能够掌握一门武林绝学&#xff0c;是全世界男人的终极梦想。可翻翻公认的武林十大绝学&#xff1a;葵花宝典、六脉神剑、九阳神功....不是断子绝孙&#xff0c;就是杀人于无形&#xff0c…

中国地区三级联动下拉菜单的实现

1.首先是js文件(area.js)&#xff1a; 1 function Dsy()2 {3 this.Items {};4 }5 Dsy.prototype.add function(id,iArray)6 {7 this.Items[id] iArray;8 }9 Dsy.prototype.Exists function(id)10 {11 if(typeof(this.Items[id]) "undefined") return false;12 r…

Java里面的arraycopy总结

当我们需要两个数组之和建立一个新的数组的时候&#xff0c;我以为数组也像字符串一样&#xff0c;相加就可以&#xff0c;错了&#xff0c;需要用到arraycopy arraycopy(被复制的数组, 从第几个元素开始复制, 要复制到的数组, 从第几个元素开始粘贴, 一共需要复制的元素个数);…

C#的dapper使用

Dapper是.NET下一个micro的ORM&#xff0c;它和Entity Framework或Nhibnate不同&#xff0c;属于轻量级的&#xff0c;并且是半自动的。Dapper只有一个代码文件&#xff0c;完全开源&#xff0c;你可以放在项目里的任何位置&#xff0c;来实现数据到对象的ORM操作&#xff0c;体…

android什么是回调,Android中的回调是什么?

小编典典回调的概念是在另一个类中完成某些工作时通知类同步/异步。有人称其为好莱坞原则&#xff1a;“不要叫我们&#xff0c;我们叫你”。这是一个例子&#xff1a;class A implements ICallback {MyObject o;B b new B(this, someParameter);Overridepublic void callback…