程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> XAF中的自定義屬性編輯器

XAF中的自定義屬性編輯器

編輯:關於.NET

XAF是什麼,如果您沒聽說過,本文可能對你沒有幫助,但如果你正在查找同樣問題的解決方法希望對你有所幫助。(注:所舉得例子全部是Web工程下的,Win工程原理相同)

XAF自動從業務類生成UI。自動的根據業務類各屬性的類型生成所需的屬性編輯器。比如,對於一個業務類中的String型的屬性,生成的是一個文本框(從界面看是那樣)。對Datetime型的屬性生成一個日期選擇框。

常用的屬性編輯器類見下表(Web工程下):

Tpye PropertyEditorType 備注 String DevExpress.ExpressApp.Web.Editors.ASPx.ASPxStringProertyEditor 展示文本框 Int32 DevExpress.ExpressApp.Web.Editors.ASPx.ASPxIntProertyEditor 展示可調整的數字輸入框 Boolean DevExpress.ExpressApp.Web.Editors.ASPx.ASPxBooleanProertyEditor 選中按鈕 Datetime DevExpress.ExpressApp.Web.Editors.ASPx.ASPxDatetimeProertyEditor 時間框 Enum DevExpress.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是商業控件,所有代碼演示所用的是官方下載的評估版本。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved