<0x00> 相对更正规的MVVM的写法
前一篇文章不是讲MVVM模型嘛,然后这几天看了看别人写的代码
确实有很多值得学习的地方
单独拆个BaseViewModel出来
之前讲到ViewModel要实现接口INotifyPropertyChanged来通知前端属性更改
基本上所有的VM都要用到的,所以最好就是有个BaseViewModel类,给所有的VM继承
具体代码如下
namespace WPFTest.VM
{
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
internal void NotifyPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
其实就是把那些代码单独拆出来了
然后所有的VM继承这个类就好了
之前也讲到RelayCommand类也是经常用到的工具类
所以一般这两个类的文件会放在同一个文件夹下
这里的命名空间也进行了规范(我这里为了简单就只写缩写了)
反正就是M/V/VM分三块地就行了
具体还是按着规范怎么舒服怎么来
另一种更舒适的方式添加DataContext
之前在前端引入VM的上下文是靠对应.cs文件里加this.DataContext=this;实现
现在有相对舒适的做法
首先要在.xaml的xmlns中引入命名空间
然后加入具体控件的DataContext
具体要添加的代码如下
<Window ...
xmlns:vm="clr-namespace:WPFTest.VM"
...>
...
<Window.DataContext>
<vm:ViewModel/>
</Window.DataContext>
...
</Window>
这里的vm可以随便改的,ViewModel是具体的VM
这样写的话就尽可能避开对应的.cs,尽可能把前端实现交给.xaml
<0x01> 关于窗口透明化
之前是在Window标签里设置AllowTransparency=True和Background="Transparent"来实现
但这样实现的窗口性能会受很大影响(相关分析可以看大佬lindexi的博客)
简单来说就是这样写会相对频繁的申请内存,让CPU和内存的负荷加大
所以怎么办呢,我们也可以通过WindowChrome实现
更多的信息可以看大佬walterlv的博客
还有大佬丑萌气质狗的博客
我这里就接着我的代码改改了
具体修改的代码如下
<!--前一个是隐藏window默认控件的,后一个是仅允许最小化的意思-->
<!--具体也不清楚为啥,后一个必须是CanMinimize或NoResize才有透明-->
<Window ...
WindowStyle="None"
ResizeMode="CanMinimize"
...>
<!--修改WindowChrome-->
<WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="-1"/>
</WindowChrome.WindowChrome>
<!--别的代码-->
<!--在Template里设置背景透明,一定别忘加ContentPresenter-->
<Window.Template>
<ControlTemplate TargetType="Window">
<Border Background="Transparent">
<Border CornerRadius="10"
Margin="10">
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<GradientStop Color="#392669"
Offset="0"/>
<GradientStop Color="#46204F"
Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Border.Effect>
<DropShadowEffect Color="Gray"
ShadowDepth="0"
BlurRadius="10"
Opacity=".5"
Direction="0"/>
</Border.Effect>
<ContentPresenter ClipToBounds="True"/>
</Border>
</Border>
</ControlTemplate>
</Window.Template>
<!--别的控件-->
</Window>
还有我们原来负责最小化和关闭程序的两个按钮要加上WindowChrome.IsHitTestVisibleInChrome="True"
这个原理在丑萌气质狗的博客里有讲
(其实建议不搞异型窗口,容易出很多莫名其妙的问题)
<0x02> 一些常用的Nuget包
WPF的强大还体现在有很多Nuget包
这些包大多是些UI组件,使WPF也可以方便的实现现代化的UI
我自己在研究的有ModernWPF和FluentWPFMordernWPF提供了些现代化的窗口和组件FluentWPF实现了Fluent设计的UI,看着好看很多
这两个用得应该还算广吧(我在很多的WPF项目里看到有用的)
性能方面还没怎么试(没研究明白)
还有一个不是专门给WPF用的,而是方便MVVM设计的
叫CommunityToolkit.Mvvm,很好用的
平时我们写MVVM模式总是要像最上面一样写一个BaseViewModel还有一个RelayCommand
这些常用的基础类已经在这个包里写好了
尤其是这玩意8.0版本加入了源代码生成器的特性,现在写属性和前端通知就很方便
具体可以看B站up-十月的寒流的视频
(人家是真大佬,他的视频做的都很不错的)
(所以我的博客就摸了😋)