• 信息系统开发平台OpenExpressApp - Command扩展机制


      下图为OpenExpressApp的系统架构图,其中在业务层中Command是作为一种系统内部提供以及可供外部扩展的一种机制。OpenExpressApp框架对功能的主要扩展之一就是Command机制,OEA提供的Command可以实现用户交互,更好的分离业务逻辑,带来更好的维护性和 可扩展性。

    Command位于架构图业务层

    Command的由来

      

    MVC是一种经典的架构模式,如上图所示:

    模型(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“模型 ”不依赖“视图”和“控制器”,也就是说,模型不关心它会被如何显示或是如何被操作(OEA现在的类库上有UI相关信息只是基于属性的一种元模型实现,它和类模型不是一个概念,大家需要区分开来),但是模型中数据的变化一般会通过一种通知机制被公布(例如:WPF中绑定属性内部实现了通知机制)。

    视图(View) 能够展现数据。在视图中一般没有业务上的逻辑。

    控制器(Controller) 控制器可以访问视图和模型,用于控制应用程序的业务流程。控制器提高了应用程序的灵活性和可配置性,它可以用来连接不同的模型和视图去完成用户的需求。给 定一些可重用的模型和视图,控制器可以根据用户的需求选择适当的模型机型处理,然后选择适当的的视图将处理结果显示给用户。

    OEA中的Command就是控制器,通过Command可以访问视图和模型,控制应用程序的业务。

    主要类图

    CommandBase

    CommandBase作为所有命令类的基类,主要定义了CanVisible、CanExecute和Execute几个方法, Execute执行方法在子类中实现。

    Code


    ViewCommand、WPFViewCommand

    ViewCommand、WPFViewCommand在CanVisible、CanExecute和Execute三个方法中传入的参数是ObjectView类型,通过ObjectView可以访问视图和模型。

    Code

    WPFListViewCommand

    WPFListViewCommand在CanVisible、CanExecute和Execute三个方法中传入的参数是ListObjectView类型。由于对ListObjectView进行扩展的比较多,所以单独实现了一个类。

    WPFAutoCommand

    WPFAutoCommand在生成窗体的View后自动调用的Command,可以在这个命令中挂接事件等。如以下代码示例:

    Code

    PropertyEditorCommand

    PropertyEditorCommand将属性编辑器PropertyEditor作为参数,框架内部的附件操作命令就是这类命令。

    代码目录结构

    Command在OEA中的目录结构如下图:

    Pattern

    Pattern目录下为codeproject上的一个扩展WPF Command的一个实现,我用它来作为OEA的command应用模式。这里就不做进一步介绍了,感兴趣的可以去那个网站看看

    CommandAdapter

    OEA是通过CommandAdapter来把CommandBase适配到Pattern

    Code

    ObjectEditCommand、TreeEditCommand、FileAttachmentCommand、LookupCommand、ViewExtCommand

    这些Command都是OEA内置对对象、树形、附件、下拉列表、View的基本操作的支持,具体代码可以去看看源码,这里就不一一列出来了。

    Code
        public class CommandNames
        {
            
    public const string Add = "Add";
            
    public const string CopyAndNew = "CopyAndNew";
            
    public const string AddChild = "AddChild";
            
    public const string DeleteBillObject = "DeleteBillObject";
            
    public const string DeleteListObject = "DeleteListObject";
            
    public const string DeleteChildObject = "DeleteChildObject";
            
    public const string Cancel = "Cancel";
            
    public const string Refresh = "Refresh";
            
    public const string Save_Bill = "Save_Bill";
            
    public const string Save_List = "Save_List";

            
    public const string InsertBefore = "InsertBefore";
            
    public const string InsertFollow = "InsertFollow";
            
    public const string MoveDown = "MoveDown";
            
    public const string MoveUp = "MoveUp";
            
    public const string LevelUp = "LevelUp";
            
    public const string LevelDown = "LevelDown";
            
    public const string ExpandAll = "ExpandAll";
            
    public const string CollapseAll = "CollapseAll";

            
    public const string ClearQueryCondition = "ClearQueryCondition";
            
    public const string QueryObject = "QueryObject";
            
            
    //Lookup
            public const string ClearLookupPropertyValue = "ClearLookupPropertyValue";

            
    //view
            public const string MaxShowView = "MaxShowView";

            
    //select
            public const string SelectAll = "SelectAll";

            
    //FileAttachment
            public const string AddFile = "AddFile";
            
    public const string OpenFile = "OpenFile";
            
    public const string FileSaveAs = "FileSaveAs";
            
    public const string ClearFile = "ClearFile";
        }

    如何使用

    1. 增加Command继承类,实现CanVisible、CanExecute和Execute方法
    2. 在类定义上增加属性标记,让OEA注册这个Command到资源库中
    3. 运行时由AutoUI自动生成对应的Command的按钮或者菜单项

    Command类

      如果我们需要对树形操作增加一个命令全部展开,那么首先需要生成一个类ExpandAllCommand,由于这个命令是对树形列表视图进行操作,所以选择从WPFListViewCommand继承过来。生成类后再在类上加上Command属性来注册命令。更多的示例可以查看OEA内部支持的一些Command。

    Code
        [Command(CommandNames.ExpandAll, Label = "全部展开", ToolTip = "全部展开")]
             public class ExpandAllCommand WPFListViewCommand
            {
                
    public override bool CanVisible(ListObjectView view)
                {
                    
    return (null != view) && ((view is ListObjectView) && ((ListObjectView)view).IsTree);
                }

                
    public override void Execute(ListObjectView view)
                {
                    (view.Control 
    as MultiObjectTreeView).ExpandAll();
                }
            }

      在类定义上增加了Command属性后,OEA会把这个Command到资源库中,以下将介绍以下属性以及OEA如何生成Command对应的按钮或者菜单项。

    基于属性的模型支持

      OEA目前对UI模型和Command模型的支持都是基于属性来定义的,Command通过CommandAttribute来定义

    Code

      另外为了方便的支持控制系统Command的是否可以使用,增加了NotAllowRemoveNotAllowNewNotAllowEdit三 个属性。如果类定义上标识了这些属性,OEA在生成Command对应按钮时会进行判断是否使用这些Command。在 OpenExpressApp.MetaModel项目ApplicationModel.cs中的业务对象元信息BusinessObjectInfo 对象中有以下方法:

    Code

    注册Command

    在OpenExpressApp.Module项目BaseModule初始化时遍历程序集类型注册Command

    Code
        /// <summary>
        
    /// 所有模块的基类
        
    /// 
        
    /// 加入业务模型 命令等
        
    /// </summary>
        public class BaseModule : IModule
        {
              /// 加入Module类在程序集内的 业务模型 命令等
            public virtual void Initialize()
            {
                
    //如果是继承自这个类的类
                if (this.GetType() != typeof(BaseModule))
                {
                    var allTypes 
    = this.GetType().Assembly.GetTypes();
                    
    foreach (var item in allTypes.Where(t => t.HasMarked<BusinessObjectAttribute>()))
                    {
                        
    //加入业务模型
                        BusinessObjectInfo bOInfo = ApplicationModel.AddBusinessObject(item);
                        
    //为业务模型加入默认命令
                        bOInfo.AddNotVisibleCommand();
                    }

                    
    foreach (var item in allTypes.Where(t => t.HasMarked<CommandAttribute>()))
                    {
                        
    //加入自定义命令
                        ApplicationModel.Commands.Add(Activator.CreateInstance(item) as CommandBase);
                    }
                }
            }
        }

    AutoUI使用Command生成按钮

      Command定义完后需要通过按钮或者菜单项在UI中表现出来,OEA通过AutoUI功能进行自动生成按钮来实现,在《AutoUI自动生成界面》中介绍的CreateMainToolBar和CreateChildToolBar中会基于Command的一些属性来过滤可以使用的命令CreateMainToolBar代码如下:

    Code

    更多内容: 开源信息系统开发平台之OpenExpressApp框架.pdf

    欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]

  • 相关阅读:
    Windows下安装Redmine
    【精华】Linux/GNOME的小技巧
    Perl简单教程
    【转载】手把手教你配置Windows2003集群(图)
    Windows 7 下如何配置PHP网站运行环境
    常用的PHP数据库操作方法(MYSQL版)
    CentOS上搭建Nginx + Mono 运行 asp.net
    【视频】Win2003 iis 流媒体设置
    【实用】OS X Lion restore Recovery HD Manually 手工创建 OS X Lion 恢复分区
    【小结】CentOS Linux操作系统的设置:
  • 原文地址:https://www.cnblogs.com/zhoujg/p/1603826.html
Copyright © 2020-2023  润新知