XAF中的自定义属性编辑器

转自:http://www.cnblogs.com/lauyee/archive/2010/06/21/1756978.html

 

XAF是什么,如果您没听说过,本文可能对你没有帮助,但如果你正在查找同样问题的解决方法希望对你有所帮助。(注:所举得例子全部是Web工程下的,Win工程原理相同)

      XAF自动从业务类生成UI。自动的根据业务类各属性的类型生成所需的属性编辑器。比如,对于一个业务类中的String型的属性,生成的是一个文本框(从界面看是那样)。对Datetime型的属性生成一个日期选择框。

常用的属性编辑器类见下表(Web工程下):

TpyePropertyEditorType备注
StringDevExpress.ExpressApp.Web.Editors.ASPx.ASPxStringProertyEditor展示文本框
Int32DevExpress.ExpressApp.Web.Editors.ASPx.ASPxIntProertyEditor展示可调整的数字输入框
BooleanDevExpress.ExpressApp.Web.Editors.ASPx.ASPxBooleanProertyEditor选中按钮
DatetimeDevExpress.ExpressApp.Web.Editors.ASPx.ASPxDatetimeProertyEditor时间框
EnumDevExpress.ExpressApp.Web.Editors.ASPx.ASPxEnumProertyEditor下拉框
<BaseObject>DevExpress.ExpressApp.Web.Editors.ASPx.ASPxLookupPropertyEditor下拉框,通常是同这个对象形成一对多的关系

      在创建业务类的时候这些对象自动和业务类的属性关联,不需要再做声明。还可以选择其他的属性编辑器。可以在Xafml文件的Application | Views | Items | PropertyEditor节点或Application | Views | Items | PropertyEditor节点找到。如:

  • 与 Rating 属性相应的 Application | Views | Items | PropertyEditor 节点:
<Application>
   <Views>
      <DetailView ID="Song_DetailView">
         <Items>
            <PropertyEditor PropertyName="Rating" 
               PropertyEditorType="MySolution.Module.Web.MySolutionAspNetModule.WebStarRatingPropertyEditor" />
         </Items>
      </DetailView>
   </Views>
</Application>
  • 与 Rating 属性相应的 Application | BOModel | Class | Member 节点:
<Application>
   <Views>
      <DetailView ID="Song_DetailView">
         <Items>
            <PropertyEditor PropertyName="Rating" 
               PropertyEditorType="MySolution.Module.Web.MySolutionAspNetModule.WebStarRatingPropertyEditor" />
         </Items>
      </DetailView>
   </Views>
</Application>

当然最好的做法是用可视化的模型编辑器,也是可以在两个节点下找到,如图:

 

      针对属性的类型不同,允许选择的类型不同。上图是字符串类型允许选择的属性编辑器。

      所有的属性编辑器都要由PropertyEditor类继承。继承结构是这样的:

      要实现一个自定义的属性编辑器,首先要确定从哪一个PropertyEditor的派生类继承,以及要是用的控件。

      现在我要做的是:实现一个一对多关系的下拉属性编辑框。下拉框的要实现成树状结构。一开始我打算从ASPxLookupPropertyEditor继承,他是业务类型默认的属性编辑器。但是这一次有点麻烦,ASPxLookupPropertyEditor类包含的控件是ASPxComboBox,ASPxComboBox控件中无法包含一颗树。因为绑定的是一个对象,而不是一个简单的值,所以上述列表中的PropertyEditor的派生类都不适合。这一次我选择继承的是ASPxObjectPropertyEditorBase类。这是对象属性编辑器的基类。ASPxLookupPropertyEditor类就由这个类继承。

     因为代码和方法相对比较少,重点只是在于你可能需要在好多个重写的方法中找到合适的那个,所以就不用画类图了。直接贴出代码:(再看代码的时候按所标注释的编号看,那是我完成代码的顺序)

001[PropertyEditor()]//为了在上图的模型编辑器中会出现你自定义的编辑器,要加上这句代码。可以有参数,表示编辑器的数据类型。
002   public class ASPxTreePropertyEditor : ASPxObjectPropertyEditorBase
003   {
004 
005       private WebLookupEditorHelper helper;
006       public ASPxTreePropertyEditor(Type objectType, IModelMemberViewItem model)
007           : base(objectType, model)
008       {
009           skipEditModeDataBind = true;
010       }
011       //1、集成了借口之后你需要实现的只有这一个重写方法,目的就在于要返回一个自定义的属性编辑器(也就是一个控件)
012       protected override WebControl CreateEditModeControlCore()
013       {
014           return CreateTreeDropDown();
015       }
016       TreeDropDown CreateTreeDropDown()
017       {
018           try
019           {
020               //2、具体的控件需要用到一个下拉书的控件,我在另一个类中实现了这个控件。
021               TreeDropDown treeDropDown = new TreeDropDown();
022 
023               treeDropDown.TreeList.DataSource = helper.CreateListView(CurrentObject).CollectionSource.List;
024               treeDropDown.TreeList.KeyFieldName = "Oid";
025               treeDropDown.TreeList.ParentFieldName = "Parent!Key";
026               treeDropDown.TreeList.ClientInstanceName = "TreeList";
027               treeDropDown.TreeList.Width = Unit.Parse("100%");
028               treeDropDown.ClientInstanceName = "DropDownEdit";
029               treeDropDown.TreeList.PreviewFieldName = "Name";
030               TreeListTextColumn col = new TreeListTextColumn();
031               col.Name = "Name";
032               col.FieldName = "Name";
033               treeDropDown.TreeList.Columns.Add(col);
034               treeDropDown.ReadOnly = true;
035               treeDropDown.TreeList.SettingsBehavior.AutoExpandAllNodes = true;
036               treeDropDown.TreeList.CustomCallback += new TreeListCustomCallbackEventHandler(TreeList_CustomCallback);
037               return treeDropDown;
038           }
039           catch (Exception e)
040           {
041               throw e;
042           }
043       }
044 
045       //7、由于ASPxTreeList没有节点点击时间,所以我用了客户端的点击事件,让他返回一个回调方法。
046       void TreeList_CustomCallback(object sender, TreeListCustomCallbackEventArgs e)
047       {
048           //这里是用户在用户改变选择项的时候,重新为属性赋值。以保存对象。
049           ((TreeDropDown)Editor).Value = helper.GetObjectByKey(CurrentObject, e.Argument);
050           EditValueChangedHandler(sender, EventArgs.Empty);
051       }
052 
053       // 6 、再绑定数据时需要用到一个helper对象,用来创建数据列表
054       public override void Setup(ObjectSpace objectSpace, XafApplication application)
055       {
056           base.Setup(objectSpace, application);
057           if (MemberInfo.IsPersistent)
058           {
059               helper = new WebLookupEditorHelper(application, objectSpace, MemberInfo.MemberTypeInfo, Model);
060           }
061           else
062           {
063               helper = new WebLookupNonPersistentEditorHelper(application, objectSpace, MemberInfo.MemberTypeInfo, Model);
064           }
065       }
066   }
067 
068   //3、之后我生成了这个类。
069   class TreeDropDown : DevExpress.Web.ASPxEditors.ASPxDropDownEdit
070   {
071       ASPxTreeList treeList;
072       public ASPxTreeList TreeList
073       {
074           get
075           {
076               return treeList;
077           }
078       }
079 
080       public TreeDropDown()
081       {
082 
083           treeList = new ASPxTreeList();
084           //4、在这个类中我需要向他添加一个包含有ASPxTreeList控件的模板,所以要实现一个ITemplate接口
085           this.DropDownWindowTemplate = new TreeListTemplate(treeList);
086       }
087       protected override void OnPreRender(EventArgs e)
088       {
089           string script = @" <script type='text/javascript'>
090           function RowClickHandler(s, e) {
091               DropDownEdit.SetKeyValue(e.nodeKey);
092               TreeList.GetNodeValues(e.nodeKey, 'Name', setDropDownText);
093               DropDownEdit.HideDropDown();
094               TreeList.PerformCallback(e.nodeKey);
095           }
096           function setDropDownText(value) {
097               DropDownEdit.SetText(value)
098           }</script>  ";
099           this.RegisterScriptBlock("", script);
100           treeList.ClientSideEvents.NodeClick = "RowClickHandler";
101           base.OnPreRender(e);
102       }
103 
104       //5、实现ITemplate接口完成一个模板项
105       class TreeListTemplate : ITemplate
106       {
107           ASPxTreeList treeList;
108           public TreeListTemplate(ASPxTreeList treeList)
109           {
110               this.treeList = treeList;
111           }
112           public void InstantiateIn(Control container)
113           {
114               container.Controls.Add(treeList);
115           }
116       }
117   }

 

      可以看得出我写代码的时候不是一气呵成,而是从抽象的顶层,从外到里。你用XAF不得不如此,框架逼着你不得不这样。会后完成的东西就是这样:

最后是打包的源代码下载(我的的是XAF10.1.4版)。我没有提供数据库,你应当知道。那对XAF框架来说是不必要的,他会自动负责生成。可能你需要在下面这个界面输一些数据用于测试。

 

 

说明:本文原代码中,用了中文属性名和如上的代码注释,只是为了演示方便,并不代表我的编程风格。另:XAF是商业控件,所有代码演示所用的是官方下载的评估版本。

转载于:https://www.cnblogs.com/Rising/archive/2010/11/27/1889567.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值