首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

XAF之深入了解Application Model

2012-07-28 
XAF之深入理解Application Model 一.鸟瞰Application ModelXAF的两大特色是1.自动生成UI;2.使用相同的业务

XAF之深入理解Application Model

 一.鸟瞰Application Model

            XAF的两大特色是1.自动生成UI;2.使用相同的业务逻辑产生不同平台的程序,而这两大特色都归功于Application Model才能完成。首先,XAF扫描程序代码,提取声明的类做出分析后创建数据结构和用户接口。扫描分析的结果是创建中性的数据格式,使用该格式定义数据库结构和程序特性,才能跨平台地读取使用。这个中性格式的元数据就是Application Model,实际上Application Model就是使用XML语言写成的文本,自然能够很方便地分享和更改,所以就为XAF程序提供了极大的自定义自由度。可以在设计时利用它修改程序配置(设置),也可以在运行时修改。由于Application Model是用XML书写的,使用简单的文本编辑器就能够对程序做出更改,但XAF提供了模块编辑器Model Editor能够很方便地修改Application Model,如图1所示。当然,也可以在代码中修改,这也是本文探讨修改Application Model的主要方式。

XAF之深入了解Application Model

图1 Application Model Editor

          Application Model将信息组织成树形结构,如图2所示。根节点是Application,根节点下有许多子节点,如图2中的ActionDesign, BOModel, CreatableItem, ImageSource, NavigationItems, ViewItems, View等等,每一个树中的节点都拥有一系列的属性,它们决定特定程序元素的特性。如果要对某类程序元素做出配置,则到对应节点下设置即可,如要配置导航栏,则展开NavigationItems节点,在其中做出适当的配置即可。

XAF之深入了解Application Model

图2 Application Model(树形结构)

         下面简单介绍几个二级节点,如图3所示。

XAF之深入了解Application Model

图3  Application Model主要节点

1.ActionDesign

       该节点下存放了程序中所有的Action的相关信息,其下的Actions节点存放了程序中所有Controller的包含的Action的定义,ActionToContainerMapping节点下是所有ActionContainer的信息,而Controllers节点下记录了所有的WindowController和ViewController,还有DisableReasons下存在了一些已声明的禁用某些UI元素的原因。

2.BOModel

      该节点下存放了所有的业务对象模型,包括XAF自带的XPO对象河我们自己定义的XPO对象。

3.NavigationItems

     该节点下存放了导航栏的项,通过对它进行设置可以改变导航栏的行为,该节点下的子节点可包含更多子节点,包含子节点的为导航分组,不包含的为导航项。

4.ViewItems

      该节点下存放了详细视图的UI元素,如PropertyEditors。

5.Views 

    该节点下存放了程序中全部视图,主要包括所有XPO对象的ListView, DetailView, LookupListView,以及DashboardView视图(图3中没有)。

     由此可见,Application Model包含了程序运行的大部分配置。经典的MVC架构的元素在这里都体现出来了,而据XAF开发团队的开发人员说,他们的确是读了MVC的基本经典著作后谋划开发的XAF,所以理解MVC架构的开发者应该很容易掌握XAF,不像我摸索地这么久,当然,这是题外话了。好了,既然XAF的配置信息都放在Application Model里了,那XAF程序是怎样使用Application Model来配置程序特性的呢,那就先要理解Application Model的分层结构了。

二. Application Model的层次结构

     在程序中不同地方自定义Application Model时,要能够意识到Model产生的顺序,即图4所示的层级结构。

XAF之深入了解Application Model

图4 Application Model的层次结构

在最底层是Application Model的零层。该层是基于程序引用的模块的代码自动产生的。在零层上,是XAF程序的各个模块,以各模块的 Xafml文件为代表。除此之外,若在程序项目中有其他引用模块的Xafml文件,它们也会生成对应的层。这些层的生成依据了它们的依赖关系。然后是程序工程即application's project的Xafml文件生成的层。在最顶部的是终端用户自定义后生成的层,它存储在WinForm程序的Model.User.xafml文件中或ASP.NET程序的浏览器cookies中。最后,还有一层叫做管理层(master layer)。它自身并不包含任何信息,它仅充当一个其他层的代理,实际上,当访问Application Model时,是和管理层在打交道。        由于Application Model拥有程序配置的大量信息,它不应该立即全部生成。每部分仅仅在需要时才生成。当需要从某个节点读取信息,该读取请求被传递给管理层,管理层接收到请求后检查第零层是否产生了对应的信息。如果没有在第零层找到,就在第零层产生部分信息,然后管理层再检查其他层,将其他层的信息加上零层的信息返回请求信息。若不同层对该节点包含了不同的数据,那么依最高一层数据为准,但并不会修改中间层的数据。当需要修改数据时,管理层将会在最顶层创建相应节点并保存。       由上述信息可以看出,Application Model是从下往上检索信息,最先检索到的是代码中的数据,如果对同一数据在多个层中都有配置的话,最后以高层数据为准。这句话很重要,我之前有一次在代码中OnActived中为ListView添加了一个过滤器并清除了其他过滤器,最后却没有数据显示,这是因为在我清除过滤器时我在Model Editor中设定的过滤器还没有附加到ListView上,当然也不会在那时被清除,两个过滤器一叠加,自然得不到想要的结果。这只是一个小例子,如果在代码中和Model Editor中同时配置了同一数据节点,就必须考虑这个层次检索问题。       理解了Application Model的运作原理,就可以方便地使用它来配置程序了。使用Model Editor配置Application Model在XAF的帮助文档中有大量的例程,我就不多做介绍了,下面的内容主要说说在代码中利用Application Model怎样来配置程序。三.在代码中使用Application Model配置XAF程序1.怎样在代码中访问Application Model        使用表1中的对象可以在代码中访问到Application Model。表1 访问Application Model的对象ObjectPropertyViewView.ModelActionBaseActionBase.ModelPropertyEditorPropertyEditor.ModelXafApplicationXafApplication.Model        这些对象通过对应的Model属性返回,它们都是IModelNode接口的后裔,利用这些对象就可以访问Application Model节点树的对应节点。Application Model树形结构的每个节点也是使用接口定义的,这些节点是IModelNode的继承者,每个接口提供了访问该类节点的属性。如Applicatioin Model的根节点是 Application节点,它是用IModelApplication接口定义的,该接口暴露了Title, Company, Description等属性和ActionDesign, Views等子节点。Application Model常见的几个接口描述请参阅XAF帮助文档http://documentation.devexpress.com/#Xaf/CustomDocument2596 。Application Model的结构支持自定义,修改节点属性值,增加新节点,拓展现有节点等等,根据需要可以实现程序的最大自由修改而无需改动大量代码。
        下面提供几个利用Application Model修改程序行为的示例,它们都是从代码中实现,这样更容易理解Application Model是怎样工作的,实际使用中大可以直接利用Model Editor来方便地完成这些操作。

2.使用Application Model改变简单的设置        XAF是非常强大的一个框架,它提供给了开发者非常多的易用的编程接口,它们都以WindowController/ViewController的形式表现,利用这些ready to use的Controller可以完成大部分程序的勾画,而现在我们不使用这些Controller,仅在新建的空的WindowController/ViewController中使用Application Model配置程序。      现在,我们要将默认的About按钮的Caption由默认的About改成Information,将程序的标题改为"change model  from code ",并输出当前所有ActionContainer的id。      利用表1的对象,我们可以访问到Application Model,然而要修改下面某节点的属性值,就必须知道该节点是什么接口定义的,不能像在Model Editor中不用管什么借口类型动动鼠标修改就行,一级一级查阅帮助文档的引用部分当然可以,但是费时费力。这里有一个小技巧:利用Model Editor!打开Model Editor,展开Actions节点,如图5所示。XAF之深入了解Application Model
图5 Actions节点
                右边是对应的详细视图,包含了选中节点的全部属性,其中我们需要的Id, Caption等属性也包含其中。而注意左下角的提示就包含了NodeType和Member of interface,NodeType就是当前选中节点的接口类型,Member of interface是说当前节点是谁的接口成员。依次点选ActionDesign, Actions, About Info,查看左下角提示,就知道对应的节点接口类型依次为IModelActionDesign, ImodelActions, IModelAction,如图6所示。XAF之深入了解Application Model
XAF之深入了解Application Model
XAF之深入了解Application Model
图6   节点接口类型               下面就可以在代码中更改。
图7  运行结果           程序的输入如下,可见的确访问到了所有ActionContainer。ActionContainer Id:ObjectsCreation
ActionContainer Id:File
ActionContainer Id:Save...................................................
...................................................
ActionContainer Id:Menu
ActionContainer Id:Windows

3.使用Application Model配置View的行为          下面,我们将利用Application Model为Persistent Object1的ListView添加一个筛选器,我们还是在代码中实现(在设计时使用Model Editor更简单,参考帮助文档http://documentation.devexpress.com/#Xaf/CustomDocument2722)。添加一个显示全部记录的ALL和一个只显示Number大于100的过滤器,如图8所示。XAF之深入了解Application Model
图8  添加过滤器      代码如下:
IModelListView listView = View.Model as IModelListView;            IModelListViewFilters filters = (IModelListViewFilters)listView.GetNode("Filters");            IModelListViewFilterItem filter1 = filters.AddNode<IModelListViewFilterItem>("all");            filter1.Caption = "All";            filter1.Criteria = null;            IModelListViewFilterItem filter2 = filters.AddNode<IModelListViewFilterItem>("filter2");            filter2.Caption = "Greater than 100";            filter2.Criteria = "[Number] > 100";            filters.CurrentFilter = filter1;            View.SetModel(listView);
            另外,这里顺便说一点。在Application Model中添加的是UI级别的过滤,即所有的数据是在加载到了程序会话后再过滤的。若要加载大量数据,除了启用ServerMode外,建议在ViewController的Actived事件中将过滤器CriteriaOperator添加到ListView.CollectionSource.Criteria字典中,这样才能避免程序假死。
           还有,在更改了View的Model后要使用View.SetModel方法重新加载Model才会使更改生效,否则只有关掉程序,下次再运行才能看到效果。而调用SetModel方法会自动调用SaveModel和 LoadModel方法。View.SaveModel将model的新配置信息保存,而View.LoadModel则从Application Model重新加载配置,更新AllowEdit, AllowNew 等等属性后,还会根据新的Model信息重建View的Control,这意味着View可能会像刚打开一样,比如之前选中的ListView某记录变成选中ListView第一条记录,某些空间的事件需要重新订阅等等。所以,若非必要,不要在代码中对Application Model尤其是Views节点做过多更改,这在使用DashboardView时体现得尤其重要。若必须要在代码中更改DashboardView的某些行为,可以尝试使用DashboardView子View在内存中的对象,对他们做出的更改会立即生效,不需要重新加载Model。4.在代码中添加新节点          有时,可能我们需要在Application Model中添加新节点,比如基于某ListView在Views节点下产生一个新的 ListView,该新 ListView默认按照某字段分组显示。除了一行一行代码地去添加外,XAF提供了一些即用的节点产生器,专门用于在Model树中添加节点。这些节点产生器和Application Model的主要节点类型一一对应,足以满足程序新建节点的要求,全部节点产生器的详细信息参阅帮助文档http://documentation.devexpress.com/#Xaf/CustomDocument3316 。示例我就不给了,帮助文档上有相关示例,非常细致:http://documentation.devexpress.com/#Xaf/CustomDocument3315 。        5.在代码中扩展Application Model的节点        还有一种情况,我们可能需要在某节点下添加新的属性。比如虽然XPO可以导入数据库表的结构和关系,但却不能导入数据库表的全部信息,在MSSQL数据库中,数据库,数据表,字段都有一个 扩展属性ExtendedProperty,我之前常使用数据表的扩展属性记录一些表的描述信息,然而它不不能被导入XPO结构中去(也不应该导入这种不同数据库的不标准属性),那么,如果一定要使用,就可以在Views或者BOModel节点下去扩展节点,为节点增加一个属性。       在代码中扩展Application Model节点的示例在帮助文档中也讲得很详细,我就不再赘述,详细信息参阅:http://documentation.devexpress.com/#Xaf/CustomDocument3169。        总而言之,Application Model使得XAF程序具有了及其强大的特性,好好理解并掌握它也就理解了XAF架构的使用,熟悉了工具,才能写出好了程序,工欲善其事,必先利其器嘛。

热点排行