前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# 值得永久收藏的WPF项目实战(经典)

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

作者头像
用户9127601
发布2021-12-17 19:16:40
4.5K1
发布2021-12-17 19:16:40
举报
文章被收录于专栏:dotNET编程大全dotNET编程大全

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运行结果

04项目说明

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

① MainWindowViewModel.cs类:

代码语言:javascript
复制
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的选择改变事件:

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

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

代码语言:javascript
复制
 <ContentControl Name="ActiveWindowView"/>

②ShellViewModel.cs类:

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

代码语言:javascript
复制
SimpleContainerViewModel simpleContainerViewModel = new SimpleContainerViewModel();
  IWindowManager windowManager = IoC.Get<IWindowManager>();
   windowManager.ShowDialog(simpleContainerViewModel);

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

代码语言:javascript
复制
 public bool CanSayHello
        {
            get { return !string.IsNullOrWhiteSpace(Name); }
        }

        public void SayHello()
        {  
        }
        

③EventAggregatorViewModel.cs

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

代码语言:javascript
复制
 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>

代码语言:javascript
复制
 private readonly IEventAggregator eventAggregator;
 this.eventAggregator = IoC.Get<IEventAggregator>(); 
 this.eventAggregator.Subscribe(this);

事件处理方法:

代码语言:javascript
复制
 public void Handle(PersonInfoEven message)
        {
            PersonInfo = message.ToString();
        }

④SimpleContainerViewModel.cs

方法1 同步ui发布事件

代码语言:javascript
复制
this.eventAggregator.PublishOnUIThread("i am a chinese");

方法2 开线程去发布

代码语言:javascript
复制
  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"

代码语言:javascript
复制
<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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 dotNET编程大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01 简介
  • 02重要知识点
  • 03运行结果
  • 04项目说明
  • 05源码下载
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档