[分享]一些在 WPF/Silverlight 中应用 MVVM 模式时可能会有点用途的代码

想来这个博客也已经有很久没更新过了,新年新气象,现在就开始写新内容吧。

最初的起因 

在最近的几个月中我做的开发总是要跟 XAML 打交道,也就是 WPF 啊,Silverlight 啊,WF 啊这些。

在进行 WPF 和 Silverlight 开发的过程中常常要用 MVVM 模式,鉴于网络上关于 MVVM 的特点的文章一抓一大把,我这里就不进一步解释 MVVM 了。

可是,在 WPF 和 Silverlight 中应用 MVVM 时,是要在 View Model 的属性被改变的时候是要触发 INotifyPropertyChanged.PropertyChanged 事件的,对于 C# 来说这部分是不能用像是“{ get; set; }”这样简化的语法来实现的;

而且 PropertyChangedEventArgs 的构造函数接受的是以 System.String 类型为载体的属性名称,这也就意味着如果把属性名称硬编码在程序中,一旦日后因为什么原因要对代码进行重构、改变属性的名称,就只能手工修改写在字符串以匹配更改之后的属性名称,在这个过程中也是很容易产生失误的。

所以往往在这个过程中开发人员可能会感到迷茫——到底 MVVM 是让事情变简单了还是变得麻烦了?

解决问题的几种办法

知道了实际应用 MVVM 模式时的困难,微软推出的 Prism 框架中便定义了 NotificationObject 类型,派生自此类型的 View Model 可以通过 RaisePropertyChanged 方法来触发 PropertyChanged 事件,而 RaisePropertyChanged 方法的其中一个重载形式接受的是签名为 Func<T> 的 Lambda 表达式,也就是说如果使用这个重载,即使我们在未来修改了属性的名称,通过 Visual Studio 的重构工具也会自动把这个改动反映到对 PropertyChanged 事件的触发中,不需要我们再手工修改字符串。

这个方法很多对表达式树有了解的人大概都想得到,实际上我自己的 ASP.NET 压缩模块和 KyuuBackground 也用了类似的方法。

但是,使用表达式树的话总会有些额外的开销的,虽然对于触发事件之后的一系列连锁反应来说这个开销可能并不是什么严重问题,但仍然有人觉得代码不够整洁,所以后来在随着 Visual Studio 2012 一起到来的新版本 .NET 框架中支持了一种新的语法,通过在像是 RaisePropertyChanged 这样的方法的签名上添加 CallerMemberName 特性,就可以在调用代码中省去传递属性名称的这个细节,同时也不用担心会像使用表达式树那样产生额外的开销。

实用的机能

可惜因为种种原因,我暂时还是只能用 Visual Studio 2010,享受不到 CallerMemberName 的便利性,并且即使是可以省去手工填入属性名称的动作,对属性的后端字段的定义、访问以及对 RaisePropertyChanged 的调用还是不能省略的,代码写着写着我也烦躁了起来。

就在这个时候,我想起来 Visual Studio 中还有个功能叫做“代码段”。

有了合适的工具,事情就好办了,于是我立即动手编写代码段。

大体上,代码段看上去是这样的:

		private $type$ m$name$$end$;public $type$ $name${get { return m$name$; }set{if (value == m$name$) return;m$name$ = value;RaisePropertyChanged(() => $name$);}}

由于后端字段和对外暴露的属性不可以重名,所以这里加了 m 字母作为前缀用以区分;同时我也经常使用 Prism 或者类似的 Library,所以是向 RaisePropertyChanged 方法中传递了一个 Lambda 表达式。

对于不使用 Prism 或者类似 Library 的开发人员,可以把对 RaisePropertyChanged 调用的这一行改为:

				RaisePropertyChanged("$name$");

而对于使用 Visual Studio 2012 的开发人员,则可以改为:

				RaisePropertyChanged();

附件中包含了完整的 .snippet 文件,可以在解压之后通过 Visual Studio 的代码段管理器导入,或者直接放入 My Code Snippets 文件夹中。

MVVM.zip

转载于:https://www.cnblogs.com/NanaLich/archive/2013/01/04/yet-another-code-snippet-for-xaml-mvvm.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机调用系统的拍照和裁剪功能,假设界面有输入框EditText,在一些手机会出现点击EditText会弹出输入法,却不能输入的情况。...

1、拍照裁剪后 点击EditText会弹出输入法&#xff0c;却不能输入。可是点击点一EdtiText就能够输入了&#xff0c;所以我就写了一个看不见的EdtiText&#xff0c;切换焦点&#xff0c;这样就攻克了这个奇怪的这问题&#xff0c;应该是android内部的问题。 这是网络一个牛人留下…

Redis一个命令请求从发送到完成的步骤以及初始化服务器步骤

一个命令请求从发送到完成的步骤 如下&#xff1a; 1、客户端将命令请求发送给服务器 当用户在客户端中键入一个命令请求时&#xff0c;客户端会将这个命令请求转换成协议格式&#xff0c;然后通过连接到服务器的套接字&#xff0c;将协议格式的命令请求发送给服务器。 2、服…

c打印行号和函数_使用C中的函数名称,行号从任何函数打印错误消息

c打印行号和函数Sometimes, it is necessary to print some message on logic failure or anytime with the function name and line number, so that program can be debugged and fixed the issue. 有时&#xff0c;有必要在逻辑故障时或在任何时候使用功能名称和行​​号打印…

Linux SPI框架

水平有限&#xff0c;描述不当之处还请指出&#xff0c;转载请注明出处http://blog.csdn.net/vanbreaker/article/details/7733476 Linux的SPI子系统采用主机驱动和外设驱动分离的思想&#xff0c;首先主机SPI控制器是一种平台设备&#xff0c;因此它以platform的方式注册进内…

dbms标识符无效_DBMS中的嵌套查询,相关的嵌套查询和集合比较运算符

dbms标识符无效嵌套查询 (Nested Queries) A query embedded in a query. This type of relation is termed as Nested Query and the Embedded Query is termed as a subquery. 查询中嵌入的查询。 这种类型的关系称为嵌套查询&#xff0c;而嵌入式查询称为子查询。 For exam…

重构——解决过长参数列表(long parameter list)

目录1、Replace Param with Query2、Preserve Whole Object3、Introduce Param Object4、Remove Flag Argument5、Combine Functions into ClassReference当我们需要在超长函数中提炼子函数时&#xff0c;如果函数内有大量的参数和临时变量&#xff0c;这将会对函数的提炼形成很…

C# 点点滴滴: out和ref

用c#很长一段时间了&#xff0c;不过基本是啥都不会&#xff0c;当C用的&#xff0c;作为写单片机的&#xff0c;还是真心觉得C比较亲切&#xff0c;呵呵。 不过总是要进步啊&#xff0c;慢慢积累呗&#xff0c;这次是写一个CAN的上位机模板出来&#xff0c;以后的项目就要彻底…

css控制图片最宽 最高值

.content img{width:expression_r(this.width > 500 && this.height < this.width ? 500:true);max-width:500px;height:expression_r(this.height >500 ? 500:true);max-height:500px; }转载于:https://www.cnblogs.com/panlin/archive/2013/01/06/2848017…

踩踩踩

http://china.findlaw.cn/laodongfa/ctjg/cy/cybc/ 二、合法裁员经济补偿标准的计算 按照《劳动合同法》第四十七条规定&#xff0c;经济补偿按劳动者在本单位工作的年限&#xff0c;每满一年支付一个月工资的标准向劳动者支付。六个月以上不满一年的&#xff0c;按一年计算;不…

c# 字节十六进制转十进制_用C中的十进制,八进制和十六进制数字初始化字节数组...

c# 字节十六进制转十进制C中的字节数组 (byte array in C) In C programming language, an unsigned char type can be used to declare byte array in C programming language. An unsigned char can contain a value from 0 to 255, which is the value of a byte. 在C编程语…

从uptime、stress、mpstat、pidstat观察CPU密集型、IO密集型、进程密集型切换的系统性能

uptime dyydyy-Lenovo-ThinkBook-14-IIL:~$ uptime10:27:10 up 7 min, 1 user, load average: 1.32, 0.99, 0.49结果分别对应&#xff1a;当前时间、系统运行时间、当前用户数目、过去 1 分钟、5 分钟、15 分钟的平均负载(Load Average) 平均负载是指单位时间内&#xff0c…

解析和创建xml

http://www.cnblogs.com/Li-Cheng/p/3610474.html 转载于:https://www.cnblogs.com/mxw272618/p/3769900.html

python - VirtualEnv virtualenvwrapper

VirtualEnv 是什么 VirtualEnv用于在一台机器上创建多个独立的python运行环境&#xff0c;VirtualEnvWrapper为前者提供了一些便利的命令行上的封装。 为什么要用 - 隔离项目之间的第三方包依赖&#xff0c;如A项目依赖django1.2.5&#xff0c;B项目依赖django1.3。- 为部署应用…

多台计算机共享内存_共享内存多处理器和指令执行| 计算机架构

多台计算机共享内存共享内存多处理器 (Shared Memory Multiprocessor) There are three types of shared memory multiprocessor: 共有三种类型的共享内存多处理器&#xff1a; UMA (Uniform Memory Access) UMA(统一内存访问) NUMA (Non- uniform Memory Access) NUMA(非统一…

htop与atop

htop htop使用详解–史上最强 atop Linux atop监控工具部署

js未看的文章

Web前端研发工程师编程能力飞升之路 在浏览器的背后&#xff08;一&#xff09; —— HTML语言的词法解析 组件化的前端开发流程 用js书写UI组件之js基础知识 GC与JS内存泄漏 蓝色理想之前端开发 w3c JavaScript Puzzlers react AngularJS入门教程 jQuery源码分析-如何做jQuery…

方法重写,隐藏在子类父类中的各种调用实践

一.子类和父类方法之间的关系 1.当子类和父类有方法完全相同的方法 namespace ConsoleApplication2 {class Program{static void Main(string[] args){B b new B();A a new A();A c new B();b.Show();a.Show();c.Show();Console.Read();}}public class A{public void Show()…

向量余弦值python_向量/矩阵的余弦值打印(元素明智的操作) 使用Python的线性代数

向量余弦值pythonPrerequisite: 先决条件&#xff1a; Defining a Vector 定义向量 Defining a Matrix 定义矩阵 Numpy is the library of function that helps to construct or manipulate matrices and vectors. The function numpy.cos(x) is a function used for generati…

centos 6.5网卡dhcp不能获得网关

环境:vmware centos6.5 添加两个虚拟网卡。一个自动获取ip(用于上网-桥接) 一个手动(与主机通信用于ssh-NAT)。 因为自已手动改了一下ifcfg-eth0里面的HWADDR地址。造成 eth0网卡不能识别。多出一个eth2的网卡。 配置eth2网卡&#xff0c;可以自动获取到ip地址 但用netstat -r…

CPU上下文切换(系统调用、进程上下文、线程上下文、中断上下文)

CPU寄存器&#xff0c;与程序计数器&#xff08;存储CPU正在执行的指令位置&#xff0c;或者即将执行的下一条指令的位置&#xff09;共同组成CPU上下文。 CPU上下文切换指的是&#xff1a;把前一个任务的CPU上下文保存起来&#xff0c;然后加载新任务的上下文到这些寄存器和程…