C# 值得永久收藏的WPF项目实战(经典)
01
—
简介
之前也写过好多篇CM框架相关的项目实战文章,比如:
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类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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 ; } } } } |
-
[
-
logger是定义的common logging的一个通用日志,需要在nuget上引用:Common.Logging.Log4Net1213;
-
ListBoxItems_SelectionChanged()是listbox的选择改变事件:
需要在前台附加事件:
-
12
<ListBox Name=
"ListBoxItems"
Grid.Column=
"0"
SelectedItem=
"{Binding SelectedItem}"
Margin=
"2"
cal:Message.Attach=
"[Event SelectionChanged] = [Action ListBoxItems_SelectionChanged]"
/>
ActiveWindowView 是我的主窗体,选择那个就激活那个
-
1
<ContentControl Name=
"ActiveWindowView"
/>
②ShellViewModel.cs类:
从ioc容器获取一个IWindowManager并显示:
-
123
SimpleContainerViewModel simpleContainerViewModel =
new
SimpleContainerViewModel();
IWindowManager windowManager = IoC.Get<IWindowManager>();
windowManager.ShowDialog(simpleContainerViewModel);
CanSayHello和SayHello,只有CanSayHello条件满足才会执行SayHello
-
12345678
public
bool
CanSayHello
{
get
{
return
!
string
.IsNullOrWhiteSpace(Name); }
}
public
void
SayHello()
{
}
③EventAggregatorViewModel.cs
双检锁线程安全的单例模式:
-
12345678910111213141516171819202122
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>
-
123
private
readonly
IEventAggregator eventAggregator;
this
.eventAggregator = IoC.Get<IEventAggregator>();
this
.eventAggregator.Subscribe(
this
);
事件处理方法:
-
1234
public
void
Handle(PersonInfoEven message)
{
PersonInfo = message.ToString();
}
④SimpleContainerViewModel.cs
方法1 同步ui发布事件
-
1
this
.eventAggregator.PublishOnUIThread(
"i am a chinese"
);
方法2 开线程去发布
-
123456789
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"
-
1
<xctk:BusyIndicator Name=
"busyIndicator"
BusyContent=
"Publish Event ..."
IsBusy=
"{Binding IsShow}"
Style=
"{x:Null}"
>
⑤ConductorViewModel.cs:此类需要继承Conductor<object>
将需要激活的实例放到ActivateItem,就可以从界面绑定激活对应实例窗体
ActivateItem(new ShellViewModel());
05
—
源码下载
项目有点长,不可能每个细节都说得到位,能看到这里的都是真爱,那么下面给出源码百度网盘链接:
-
123456789
网盘链接:
https:
//pan.baidu.com/s/18LOVAIxy7WCWJisiPcOuAQ
提取码:添加小编微信获取
小编微信:mm1552923
公众号:dotNet编程大全
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)