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

 

运行结果

 

 

 

04

 

项目说明

 

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

 

 

 

① 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编程大全
    

文章出处:https://www.cnblogs.com/zls366/p/15807353.html

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
管理员
上一篇:使用.NET 6开发TodoList应用(30)——实现Docker打包和部署
下一篇:使用.NET 6开发TodoList应用(29)——实现静态字符串本地化功能
评论列表

发表评论

评论内容
昵称:
关联文章

C# 值得永久收藏WPF项目实战(经典)
git仓库子模块(submodule)项目实战应用
C# WPF MVVM模式Prism框架从零搭建(经典)
企业项目实战.Net Core +FastReport教程一|制作报表模板
C#使用Thrift作为RPC框架实战(四)之TSocket
[WPF] 实现 WPF Inner Shadow
C# CefSharp使用
WPF_15_格式化绑定数据
WPF程序级资源
C#进化——C#发展史、C#1.0-10.0语法系统性梳理、C#与JAVA对比
C# 使用Roslyn编译项目 .csproj
dotnetCampus.UITest.WPF 一个支持中文用例界面单元测试框架
C# Roslyn编译csproj项目 使用Roslyn编译整个C#项目
C#未来一点感悟
WPF对象级资源
【OpenXml】Pptx边框虚线转为WPF边框虚线
[WPF] 实现一个很久以前流行按钮样式
[WPF] 抄一个 CSS3 实现按钮
[WPF] 用 OpacityMask 模仿 UWP Text Shimmer 动画
[WPF] 使用 Shazzam Shader Editor 编写一个 Lighten Effect

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码