C# 关于MVVM的思考

因为之前一直在做游戏,接触的框架的数据和视图的结构都是MVC的,第一次听说MVVM,也少不了一顿查,所幸这些结构思路大差不差,只是部分细节不同而已。

一、初识MVVM

MVVM就是M-V-VM。M是数据类,V是视图类,VM是一个中介类。它的初衷也是为了分离数据和视图,它希望三个模块职责非常单一,V只负责UI的显示,M只保存数据,VM作为V和M的中介,负责数据的传递和更新逻辑、以及glue code,这样做以后,除非UI布局或结构修改,就再也不用关心UI相关的内容了。

MVVM强调的是一种一一对应的关系,即,一个V,对应一个固定的VM,对应一个M。V和VM进行数据绑定,当M的数据发生变化时,通知VM,VM通过绑定使V自动进行更新;V触发数据更新时,通过数据绑定自动更新VM端,VM再通知M进行更新。

二、需求分析

目前需求是希望在已有的功能和结构上,分析MVVM的可行性。

现在有多个类型的数据,每种数据对应一个管理器,但是这些数据对应同一个视图。

C# 关于MVVM的思考

如图,选中某个管理器标签,显示对应的数据结构(罗列在下面)。

当前内容最重要的一点是:每个管理器添加了Attribute,在整个功能入口处进行Attribute检测,找出所有标记了Attribute的管理器,然后UI通过反射,拿到所有管理器对应的数据结构进行显示(这么做是为了以后动态添加管理器,就不需要修改UI相关代码,UI会根据检测到的标签自动生成)。

现在这些数据可以通过UI进行修改并保存,这样UI的功能就不仅仅是显示数据了,还有修改数据的权利。因此想到了MVVM的结构,将显示用到的数据进行V和VM的数据绑定,这样当数据端有变化时,V会自动更新显示;当V修改数据时,VM会自动更新数据,以后数据的变化就实现了自动化。

三、碰到的问题

理想是美好的,现实是残酷的。

首先碰到的第一个问题就是,原本的V和VM是一一对应的关系,但是目前的情况是唯一的V对应多个VM,而且V并不知道VM的所持有的具体数据类型(V里用到的数据都是反射得来的),如果像传统V和VM的绑定,V清楚知道VM里的每一个数据类型,但这样做的话我们的反射就失去了意义,“自动化”也没有用了。

为了解决这个问题,我们的V就不在关心具体数据了,而是关心每个VM是否发生变化,如果某个VM变化,就对这个VM进行绑定更新,反过来,V进行数据修改了,一样的逻辑。

第二个问题是第一个解决方案衍生出来的:当在V中对每个VM进行监听时,等等,V知道了VM的个数和具体是哪些VM?这跟我们的自动化矛盾了!V所知道的关于VM的所有信息,都是在运行时根据反射动态得到的,如果这么直接监听,就默认V知道所有VM了,自动化某的作用了。