CommonOperWindow

来源:互联网 发布:airplay mac 编辑:程序博客网 时间:2024/06/05 21:49

公共窗体的主要文件

  • USPart.DependencyLib.View.CommonView.CommonOper:主窗体,分为Toolbar和内容窗体两个部分,都是add进来的,类似一个转发器的功能,实现Toolbar和内容窗体之间的事件转发。
  • USPart.DependencyLib.View.CommonView.WindowCommonTools:Toolbar,也就是按钮条窗体,其中按钮全部通过动态add。
  • USPart.DependencyLib.View.CommonView.DefaultWindow:主窗体CommonOper的载体,DefaultWindow的content设置为CommonOper。
  • USPart.DependencyLib.BusinessObj.IOperViewInterface:基础接口,所有的内容窗体必须实现该接口,该接口中的startOperation是所有按钮点击事件的转发器,转发到对应需要执行的方法中。
  • USPart.DependencyLib.BusinessObj.IDefaultOperViewInterface:窗体默认通用接口,继承基础接口,定义了一套新增、删除、编辑、取消、保存、定位按钮组合;继承该接口的内容窗体最多可实现该接口中已有的按钮。

Toolbar和内容窗体交互原理

Toolbar中按钮点击事件传递到内容窗体实现过程

通过在WindowCommonTools中定义一个事件,该事件在按钮点击后执行。在主窗体CommonOper加载WindowCommonTools的时候给上述事件加上执行代码,该代码逻辑就是将内容窗体作为基础接口(这就是为什么内容窗体必须继承该基础接口的原因)的一个对象,执行其中的转发器startOperation,该方法的实现功能是将传递进来的方法名,通过反射的方式在当前执行,这里约定一致的写法如下:

public void startOperation(CommonToolArgs commonToolArgs){   try    {       Type t = this.GetType();       //commonToolArgs.btnTag为需要执行的方法名       MethodInfo m = t.GetMethod(commonToolArgs.btnTag);       m.Invoke(this, new CommonToolArgs[] { commonToolArgs });    }    catch (Exception ex)    {    }}

这样就实现了点击对应Toolbar中的按钮,执行内容窗体中对应的方法。

内容窗体中相关操作引发Toolbar状态改变的实现过程

这和上面所讲到过程实际是一个相反的过程,那我们就反过来做。在内容窗体上面定义一个事件,并在当前某些行为下执行该事件。而实现该事件的代码仍然放在主窗体CommonOper中,该代码利用CommonOper窗体中WindowCommonTools的对象,来访问其中公开的方法或者属性,从何达到操纵Toolbar的目标。但是该事件和在Toolbar中的事件情况又不一样,Toolbar是公共的,所有的窗体用的都是一个,所以其中定义的事件是固定的。但是内容窗体是变化的,这里为了要求内容窗体必须要实现对应事件,在基础接口IOperViewInterface中加了两个事件:

/// <summary>/// 改变ToolBar状态的事件,主要分为加载中、默认、新增、编辑/// </summary>event ChangeToolBarStatusDelegate ChangeToolBarStatusEvent;/// <summary>/// 在toolbar中显示tips/// </summary>event ChangeToolBarTipsDelegate ChangeToolBarTipsEvent;

具体使用事例和细节分析

窗体的运行事例

在run类的磁贴点击事件中

//定义窗体转发器CommonOpe commonOper = new CommonOper();//初始化Toolbar中的按钮if (commonOper.cTools != null){    //这里的parms= ConfigerSplit.strConfigerSplit(WidgetParamter.ConfigInfo.ParmsExpression)    //这个webservice初始化都是应该一致的,可以参考USPart.Parcel.Run.Run_Parcel_Asset中的代码    webservice.Client.GetA7_FCCFGByParmsCompleted += (sender, e) =>    {        if (e.Error == null)        {            //通过从wcf中获取的按钮对象填充按钮组,这里的代码是无需调整的,不过有更好的实现办法可以提出建议修改            commonOper.cTools.Init(ToolBarHelper.GetToolBarBtns(e.Result));        }    };    //这里的传递的参数是所有的参数类,这是了为方便wcf中通过如"ADD=1;"来找到对应按钮对象而做的比较好的一个方式,个人觉得减少了代码的复制度和增加整洁性,看官可以看过对应wcf中的方法后给出更多的建议    webservice.Client.GetA7_FCCFGByParmsAsync(parms);}//内容窗体,这里是土地信息,这个地方到时候开发者需要更换各自的窗体Parcel_Widget parcelWidget = new Parcel_Widget();//将配置文件中的配置信息传递给内容窗体的parm属性,这个是为了传递一些比如域名之类的信息到内容窗体中,建议统一在内容窗体中都加一个parm属性parcelWidget.parm = parms;//将内容窗体加入转发器中commonOper.Init<Parcel_Widget>(parcelWidget);//调用窗体载体DefaultWindow defaultWindow = new DefaultWindow();//窗体名称defaultWindow.Title = WidgetParamter.ConfigInfo.Caption;defaultWindow.Content = commonOper;defaultWindow.Show(0,0);defaultWindow.ChildWindowClose = ChildWindowClose;defaultWindow.CloseButton_Click = CloseButton_Click;

内容窗体简单分析

基础功能分析

假如目前需要实现一个窗体,其按钮功能最多有新增、删除、编辑、取消、保存、定位功能,那么只需要该内容窗体实现接口IDefaultOperViewInterface,其中startOperation按钮上面说的方式实现,其他方法实现该内容窗体需要实现的功能即可。这里建议代码风格参考USPart.Parcel.View.Parcel_Widget。

提示功能分析

目前Toolbar有实现一个小的tips的提示,比如如果你的内容窗体实现了保存功能,那边你会看到当你保存成功或者失败的时候,会有一个小的提示语在Toolbar中显示后自动消失。这个就是利用基础接口中的ChangeToolBarTipsEvent事件实现的,具体代码请参考USPart.Parcel.View.Parcel_Widget,这里就不列出来了。但是目前该tips仅仅实现了保存成功和保存失败两种状态下的两种风格的样式的提示,提示语是内容窗体传递过去的。然而是否需要更加多样的样式呢,有待考虑。

拓展功能分析

然而按钮组肯定不会只有IDefaultOperViewInterface中列举出来的这么多,肯定还会有其他的按钮出现。但是是否将所有可能的按钮都定义到该接口中呢,我觉得是没有必要的。这仅仅是一个默认的接口,实际就是一个默认的按钮组。接下来,可能我某一个专题在这些基础接口的基础上,需要有一个打印的按钮。那么很简单,我们可以在对应专题定义一个接口继承默认接口,如:

public interface IXXXOperViewInterface :IDefaultOperViewInterface{    void printOperation();}

然后在运维管理的操作项中查找是否存在这个按钮,如果存在,查看描述项,会有类似{‘Order’:’50’,’Tag’:’printOperation’,’Style’:’printButtonStyle’,’ToolTip’:’打印’},根据描述中的JSON对,Order表示按钮显示的位置,数据越大越靠后,尽量不要重复;Tag为接口中定义的方法;Style按钮的样式,定义在全局样式文件中;ToolTips为鼠标放置到按钮上出现的提示语,在全局的样式中定义打印按钮的样式,并将接口中的方法命名上面代码这样;如果不存在,那就增加一个这样的按钮,按照其他按钮的规则,加好按钮,并配置样式。但是有时候某个专题需要的按钮很乱,那我们只需要继承基础接口,然后按照上面的方法操作定义一套自己的接口就可以了。

0 0