WPF的原理与MVVM模式的思考
对于一般程序语言,执行分为3种:1)编译成二进制机器代码,由操作系统调用执行;典型的如C,C++,Delphi等.2)编译成中间语言,由虚拟机解释来执行或及时编译后执行(前者的典型是java,后者的典型是DotNet).3)不进行编译,有解释器边解释边执行,比较典型的
对于一般程序语言,执行分为3种:
1)编译成二进制机器代码,由操作系统调用执行;典型的如C,C++,Delphi等.
2)编译成中间语言,由虚拟机解释来执行或及时编译后执行(前者的典型是java,后者的典型是DotNet).
3)不进行编译,有解释器边解释边执行,比较典型的是VB和HTML,Javascript.等
上边这些与WPF有关系么?其实是有的,至少原理上非常相似.我们来看看WPF的XAML的执行机制:
1)首先是实例化页面类;
2)然后构建界面元素(控件树),这里很关键,因为xaml文件里有界面元素的描述性信息,对于一个界面元素E:
A)首先实例化E,知道界面元素的类名,利用反射机制很容易实例化该类.
B)设置属性,同样利用反射机制,将字符串描述的属性值设置赋给实例,这个原理很简单,但要做得很好,是需要一个简单的解释器的.
C)属性可以挂接,事件也当然可以动态挂接,但一般情况下,事件挂接时目标方法只能在页面实例里。
D)到此,一个界面元素就内存实例化了,然后放入当前页面的控件树里。实例化界面元素本来就是递归完成的,控件树的完成比较容易。
当然最后,会将有Name的元素实例赋给页面类实例里相应的成员变量,这样页面代码方法里应用该控件的代码就能正常执行了。这种执行机制与上面提到的3种方式中的第3种方式非常类似。页面元素属性(包括事件)的描述和具体页面代码分开的方式,很多地方都采用,比如Aspx,Dfm等。
从上述的过程我们可以看出,如果将这些页面元素的属性,事件按照一定的规则,其对应的具体属性值来源和事件处理代码放到另外一个类里,而不是放在与页面对应的类里,其实就是MVVM模式的视图和视图模型方式。而微软就是利用了绑定规则加上依赖属性(具体的实现原理可参考我前面的博文),附加属性等完成这种视图与处理代码的分离。
MVVM具有很大的灵活性,但无论怎么分,需要干的事情还是需要干,只不过从直接变为了间接。从分离分工的角度来说这种方式很好,但对于编程的简洁性来说,其实是不利的。而且大量的利用发射机制,性能上的损失会比较大,不过,你选择使用这种方式,就意味着你可以忍受一定的性能损失,而换取它的好处。目前来说,MVVM模式我觉得对于交互简单的页面还是非常好,但对于页面交互逻辑比较复杂的情况,还是非常不利。比如关联性交互,就是一个控件的状态发生改变,其它的控件也会跟着改变,甚至交互逻辑也会改变,直接控制变为间接控制就非常麻烦,到最后,采用这种MVVM模式会使得,VM其实就成了页面的又一个的.cs文件。
其实我们在使用MVVM模式时,没必要完全拘泥于这种理论性指导,虽然,我们可以尽可能的朝着MVVM的目标走,但如果确实需要在.cs控制,那么就大胆的用。因为大部分的示例大多时候都只能反映事情的一个面。
后记:其实由XAML格式的界面元素描述生成界面元素的实例的过程其实就是类的反序列化过程。当然C#里提供的类的xml格式序列化类并不能进行xaml格式的反序列化,但原理还是一样的。
更多推荐
所有评论(0)