【干货】个人工作文档节选:XAML MVVM 框架易用性细节优化Tips
1 易用性细节优化
1.1 代码片段
在ViewModel内,会有大量重复性的在Property set中激发 INotifyPropertyChanged.PropertyChanged 事件的代码。 这种属性用已有的代码片段已经很难高效的输入。使用合适的代码片段在VM设计时 不会因为过于机械的修改影响设计思路
1.1.1 Property Code Snippets
在项目模板中加入对应的code snippet
Sample:
键入 propvm [Tab] [Tab]后 产生如下代码
private int _PropertyName; public int PropertyName {
get { return _PropertyName; } set { _PropertyName=value; RaisePropertyChanged(()=>PropertyName); } }
1.1.2 Command Code Snippets
同样作为Command<Object> 的属性 也需要类似的code snippets
Sample:
键入 propcmd[Tab] [Tab]后 产生如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | private Command<Object> _CommandName= new Command<Object> ( p=>{}, p=> true ); public Command< Object > CommandName { get { return _CommandName; } set { _CommandName =value; RaisePropertyChanged(()=>CommandName); } } |
1.2 设计时支持
作为MVVM的UI开发设计基础,一个生产力足够高的框架应当能够为设计时提供VM的结构成员和设计时数据支持。
1.2.1 步骤:在设计视图添加设计时VM.
假设我们有一个ViewModel 类型为 My.Project.TestViewModel
在设计器正确引入如下命名空间时
<UserControl … </UserControl>
|
在设计器根节点加入
<d:FrameworkElement.DataContext> </d:FrameworkElement.DataContext>
|
这时设计器会为View指定一个TestViewModel的新实例,此时绑定会用这个新实例为模板进行设计时支持,比如所见即所得的绑定结果显示,以及模板设计支持。
对于早期版本的 VS,或者WPF/SL 以外不能支持 blend设计时命名空间的平台,d:DataContext 不被设计时支持, 这时候我们可能需要直接使用 <FrameworkElement.DataContext> 标记。这样做的代价可能是额外产生一个 ViewModel 对象引用。 如果我们能够控制好 ViewModel 默认构造函数中调用的资源,这样做问题并不大,不失为一种办法。
1.2.2 步骤:在VM添加设计时数据与逻辑
由于设计时设计器会创建一个VM实例来帮助设计,VM的设计需要注意以下几点
l VM要具有默认构造函数,否则设计器无法将其实例化
l VM中的逻辑要能够判断当前运行环境是否在设计时
n 使用大量珍贵资源的逻辑在设计时不允许运行,比如
u Timer 逻辑
u IO操作
应当在适当位置添加 “IsInDesignMode” 静态属性,建议在 ViewModelBase中添加。
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 | static bool ? _IsInDesignMode; /// <summary> /// <para>Gets if the code is running in design time. </para> /// <para>读取目前是否在设计时状态。</para> /// </summary> public static bool IsInDesignMode { get { return ( _IsInDesignMode ?? ( _IsInDesignMode = #if SILVERLIGHT_5||WINDOWS_PHONE_8||WINDOWS_PHONE_7 DesignerProperties.IsInDesignTool #elif NETFX_CORE Windows.ApplicationModel.DesignMode.DesignModeEnabled #else ( bool )System.ComponentModel.DependencyPropertyDescriptor .FromProperty( DesignerProperties.IsInDesignModeProperty, <br><br><br><br> typeof (System.Windows.FrameworkElement)) .Metadata .DefaultValue #endif )) .Value; } } |
在实现了这个属性之后 在具体Vm的构造函数或Onload事件中用户就可以添加伪数据,也可以避免不能再设计时调用的功能被调用
比如下面这段代码
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 | protected override async Task OnBindedViewLoad(MVVMSidekick.Views.IView view) { await base .OnBindedViewLoad(view); if (IsInDesignMode) { HelloWorld = "Hello Mvvm world, Design mode sample" ; } else { if (Id == null ) { Id = Guid.NewGuid().ToString(); } GetValueContainer(x => x.CountDown).GetNullObservable() .Subscribe( _ => { HelloWorld = string .Format( "Loading {0}" , CountDown); } ); } } |
当然, MVVM-Sidekick 这些方面做的都很不错。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端