程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> winform程序對界面上控件的統一控制【二】組件版

winform程序對界面上控件的統一控制【二】組件版

編輯:關於.NET

繼上篇文章winform 程序對界面上控件的統一控制【一】(賦值\清空\驗證… …) ,本篇文章將實現一個同樣功能的Component(組件)。

先看看組件的實現,如下所示:

代碼一

public partial class CtrlValidation : Component
     {
         public CtrlValidation()
         {
             InitializeComponent();
             typeCache = new TypeCache();
         }
         public CtrlValidation(IContainer container)
         {
             container.Add(this);
             InitializeComponent();
             typeCache = new TypeCache();
         }
         TypeCache typeCache;
         List<RealSailing.UI.Utils.SetControl>  ctrlCollect = new List<RealSailing.UI.Utils.SetControl>();
         [Description("控件集合")]
         [Editor(typeof(DropEditor), typeof(UITypeEditor))]
         [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
         public List<RealSailing.UI.Utils.SetControl>  CtrlCollect
         {
             get
             {
                 return ctrlCollect;
             }
             set
             {
                 ctrlCollect = value;
             }
         }
         private object dataSource;
         [Category("CatData"), DefaultValue((string)null),  RefreshProperties(RefreshProperties.Repaint),
         Description("DataGridDataSourceDescr"),  AttributeProvider(typeof(IListSource))]
         public object DataSource
         {
             get
             {
                 return this.dataSource;
             }
             set
             {
                 if (((value != null) &&  !(value is IList)) && !(value is IListSource))
                 {
                     throw new  ArgumentException("BadDataSourceForComplexBinding");
                 }
                 if ((this.dataSource == null) ||  !this.dataSource.Equals(value))
                 {
                     if (((value == null) ||  (value == Convert.DBNull)) && ((this.DataMember !=  null) && (this.DataMember.Length != 0)))
                     {
                         this.dataSource =  null;
                         this.DataMember =  "";
                     }
                     else
                     {
                         if (value !=  null)
                         {
                             this.dataSource = value;
                         }
                     }
                 }
             }
         }
         private string dataMember;
         [DefaultValue((string)null), Description ("DataGridDataMemberDescr"),
         Category("CatData"),
         Editor ("System.Windows.Forms.Design.DataMemberListEditor, System.Design,  Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",  typeof(UITypeEditor))]
         public string DataMember
         {
             get
             {
                 return this.dataMember;
             }
             set
             {
                 if ((this.dataMember == null) ||  !this.dataMember.Equals(value))
                 {
                     this.dataMember =  value;
                 }
             }
         }
         #region 提供方法
         /// <summary>
         /// 必填項是否為空,true表示不為空,FALSE表示為空
         /// </summary>
         /// <returns></returns>
         public bool CheckIsNull()
         {
             foreach (RealSailing.UI.Utils.SetControl  ctrl in ctrlCollect)
             {
                 object[] obj = new object[] {  ctrl };
                 TypeProcess _process =  TypeFactory.CreateType(ctrl.ControlName.GetType().Name, obj,  ctrl.ToString(), typeCache);
                 bool editnull =  _process.CheckNull();
                 if (!editnull)
                     return editnull;
             }
             return true;
         }
         /// <summary>
         /// 輸入框的格式是否正確,true表示正確,FALSE表示不 正確
         /// </summary>
         /// <returns></returns>
         public bool CheckIsFormate()
         {
             foreach (RealSailing.UI.Utils.SetControl  ctrl in ctrlCollect)
             {
                 if (ctrl.ControlName.GetType ().Equals(typeof(DevExpress.XtraEditors.TextEdit)))
                 {
                     object[] obj = new  object[] { ctrl };
                     TypeProcess _process =  TypeFactory.CreateType(ctrl.ControlName.GetType().Name, obj,  ctrl.ToString(), typeCache);
                     bool editformate =  _process.CheckFormate();
                     if (!editformate)
                         return  editformate;
                 }
             }
             return true;
         }
         /// <summary>
         /// 清空畫面
         /// </summary>
         public void SetCtrlClear()
         {
             ctrlCollect.ForEach(ctrl =>
             {
                 object[] obj = new object[] {  ctrl };
                 TypeProcess _process =  TypeFactory.CreateType(ctrl.ControlName.GetType().Name, obj,  ctrl.ToString(), typeCache);
                 _process.SetCtrlClear();
             });
         }
         /// <summary>
         /// 設置控件可用狀態
         /// </summary>
         /// <param name="enable"></param>
         public void SetCtrlEnable(bool enable)
         {
             ctrlCollect.ForEach(ctrl =>
             {
                 object[] obj = new object[] {  ctrl };
                 TypeProcess _process =  TypeFactory.CreateType(ctrl.ControlName.GetType().Name, obj,  ctrl.ToString(), typeCache);
                 _process.SetCtrlEnable(enable);
             });
         }
         /// <summary>
         /// 設置控件默認值
         /// </summary>
         public void SetCtrlDefault()
         {
             ctrlCollect.ForEach(ctrl =>
             {
                 object[] obj = new object[] {  ctrl };
                 TypeProcess _process =  TypeFactory.CreateType(ctrl.ControlName.GetType().Name, obj,  ctrl.ToString(), typeCache);
                 _process.SetCtrlDefault();
             });
         }
         /// <summary>
         /// 清除錯誤提示信息
         /// </summary>
         public void ClearErrText()
         {
             ctrlCollect.ForEach(ctrl =>
             {
                 object[] obj = new object[] {  ctrl };
                 TypeProcess _process =  TypeFactory.CreateType(ctrl.ControlName.GetType().Name, obj,  ctrl.ToString(), typeCache);
                 _process.ClearErrText();
             });
         }
         /// <summary>
         /// 將數據行的值映射到文本編輯框中
         /// </summary>
         /// <param name="row"></param>
         public void LoadEditRowToText(DataRow row)
         {
             if (row != null)
             {
                 ctrlCollect.ForEach(ctrl =>
                 {
                     object[] obj = new  object[] { ctrl };
                     TypeProcess _process =  TypeFactory.CreateType(ctrl.ControlName.GetType().Name, obj,  ctrl.ToString(), typeCache);
                     _process.LoadToText (row);
                 });
             }
         }
         /// <summary>
         /// 將編輯框中的數據賦給數據行
         /// </summary>
         /// <param name="row"></param>
         public void SetCtrlTextToEditRow(DataRow row)
         {
             if (row != null)
             {
                 ctrlCollect.ForEach(ctrl =>
                 {
                     object[] obj = new  object[] { ctrl };
                     TypeProcess _process =  TypeFactory.CreateType(ctrl.ControlName.GetType().Name, obj,  ctrl.ToString(), typeCache);
                     _process.SetTextToRow (row);
                 });
             }
         }
         #endregion
     }

在上面的CtrlValidation類型中,提供了三個屬性,DataSource和DataMember 屬性為數據綁定屬性,和普通的.net控件一樣,綁定到數據對象,不過本例中只 能綁定到DataSet,並且需要指定它的DataTable。最為重要的是CtrlCollect屬性 ,其類型為 List<RealSailing.UI.Utils.SetControl>,表示控件的集合 。並且該屬性設置了Editor特性(指定用來更改屬性的編輯器。無法繼承此類。 (MSDN))。並用DropEditor和基類型UITypeEditor初始化EditorAttribute類的新 實例。接下來我們看看DropEditor類型,如何的實現:

代碼二

/// <summary>
     /// 可見下拉框屬性,下拉框為用戶控件
     /// </summary>
     public class DropEditor : UITypeEditor
     {
         /// <summary>
         /// 獲取由 EditValue 方法使用的編輯器樣式
         /// </summary>
         /// <param name="context"></param>
         /// <returns></returns>
         public override UITypeEditorEditStyle  GetEditStyle(ITypeDescriptorContext context)
         {
             if (context != null &&  context.Instance != null)
             {
                 return  UITypeEditorEditStyle.Modal;
             }
             return base.GetEditStyle(context);
         }
         /// <summary>
         /// 使用指定的服務提供程序和上下文編輯指定對象的值 。
         /// </summary>
         /// <param name="context">可用於獲取附加上下 文信息的 ITypeDescriptorContext。</param>
         /// <param name="provider">IServiceProvider ,通過它可能獲得編輯服務。</param>
         /// <param name="value">正在編輯的值的實例。 </param>
         /// <returns>新的對象值。如果該對象的值尚未更 改,則這應返回與傳遞給它的對象相同的對象</returns>
         public override object EditValue (ITypeDescriptorContext context, IServiceProvider provider, object  value)
         {
             //為 UITypeEditor 提供一個接口,用於顯示  Windows 窗體,或者在設計模式下在屬性網格控件的下拉區域中顯示控件。
             IWindowsFormsEditorService iws =  (IWindowsFormsEditorService)provider.GetService(
                 typeof (IWindowsFormsEditorService));
             if (iws != null)
             {
                 using (FrmChoose UIControl = new  FrmChoose(context, (List<RealSailing.UI.Utils.SetControl>) value))
                 {
                     if (iws.ShowDialog (UIControl) == DialogResult.OK)
                     {
                         value =  UIControl.Value;
                         context.OnComponentChanged();
                     }
                 }
             }
             return value;
         }
     }

DropEditor繼承UITypeEditor(自提供可用於設計值編輯器的基類,這些編輯 器可提供用戶界面 (UI),用來表示和編輯所支持的數據類型的對象值。(MSDN)) 類型。並重寫GetEditStyle( 獲取由 EditValue 方法使用的編輯器樣式)和 EditValue(使用 GetEditStyle 方法所指示的編輯器樣式編輯指定對象的值。)方 法,前者返回UITypeEditorEditStyle,得到此編輯器的樣式,本例中的選擇的是 Modal樣式,顯示一個省略號 (...) 按鈕;後者返回object類型,表示編輯對象 的值。在EditValue方法中,調用一個窗體FrmChoose,給CtrlValidation中的屬 性CtrlCollect賦值。再來看看FrmChoose窗體時如何實現的?

代碼三

public partial class FrmChoose : Form
     {
         public FrmChoose()
         {
             InitializeComponent();
         }
         /// <summary>
         /// 
         /// </summary>
         /// <param name="context"></param>
         /// <param name="value"></param>
         public FrmChoose(ITypeDescriptorContext context,  List<RealSailing.UI.Utils.SetControl> value)
         {
             InitializeComponent();
             this.SetStyle (System.Windows.Forms.ControlStyles.DoubleBuffer |  System.Windows.Forms.ControlStyles.UserPaint |  System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);
             this.BackColor =  System.Drawing.SystemColors.Control;
             if (0 != value.Count)
             {
                 control = value;
                 foreach (object c in  context.Container.Components)
                 {
                     if (c.GetType ().BaseType.Equals(typeof(RealSailing.DataSet.BaseDataSet)))
                         FillCombFiled (context, c);
                 }
             }
             else
             {
                 RealSailing.UI.Utils.SetControl  setControl;
                 foreach (object c in  context.Container.Components)
                 {                     
                     if (arrType.Contains (c.GetType()))
                     {
                         setControl = new  RealSailing.UI.Utils.SetControl
                         {
                             ControlName  = c,
                             NullAble =  false,
                             Default =  null,
                             Formate =  "",
                             KeyFiled =  false,
                             FiledName =  ""
                         };
                         control.Add (setControl);
                     }
                     else if (c.GetType ().BaseType.Equals(typeof(RealSailing.DataSet.BaseDataSet)))
                     {
                         FillCombFiled (context, c);
                     }
                 }
             }
             this.gcSelect.DataSource = control;
         }
         /// <summary>
         /// 用數據集中的列填充ComboBoxEdit控件
         /// </summary>
         /// <param name="context"></param>
         /// <param name="c"></param>
         private void FillCombFiled(ITypeDescriptorContext  context, object c)
         {
             RealSailing.DataSet.BaseDataSet myDs = c  as RealSailing.DataSet.BaseDataSet;
             Type t = context.Instance.GetType();
             System.Reflection.PropertyInfo p =  t.GetProperty("DataMember");
             object obj = p.GetValue(context.Instance,  null);
             string table = obj == null ? "" :  obj.ToString();
             if (myDs != null && ! string.IsNullOrEmpty(table))
             {
                 DataColumnCollection cols =  myDs.Tables[table].Columns;
                 if(!cols.Contains(" "))
                     cols.Add(" ", typeof (string));
                 combFiled.Items.Clear();
                 foreach (DataColumn col in  cols)
                 {
                     combFiled.Items.Add (col.ColumnName);
                 }
             }
         }
         /// <summary>
         /// 驗證控件類型
         /// </summary>
         ArrayList arrType = new ArrayList
         {
             typeof (DevExpress.XtraEditors.LookUpEdit),
             typeof(DevExpress.XtraEditors.TextEdit),
             typeof(DevExpress.XtraEditors.DateEdit),
             typeof (DevExpress.XtraEditors.ComboBoxEdit),
             typeof (RealSailing.UI.Common.UCSysParaslkEdit),
             typeof (RealSailing.UI.Control.TextBoxEx),
             typeof (RealSailing.UI.Control.MemoEditEx),
             typeof (RealSailing.UI.Common.UCComboBox),
             typeof (RealSailing.UI.Control.PopuLookUpedit),
             typeof(RealSailing.UI.Control.UCTextEdit)
         };
         /// <summary>
         /// 控件驗證項
         /// </summary>
         List<RealSailing.UI.Utils.SetControl> control  = new List<RealSailing.UI.Utils.SetControl>();

         /// <summary>
         /// 設置的值
         /// </summary>
         public List<RealSailing.UI.Utils.SetControl>  Value
         {
             get
             {
                 return control;
             }
         }
         private void btnOk_Click(object sender,  EventArgs e)
         {
             this.Refresh();
             this.Close();
         }
         private void btnCancel_Click(object sender,  EventArgs e)
         {
             this.Close();
         }
     }

說明:

(1)該窗體上只包括一個GridControl(Devexpress)控件,並且在gridview中 添加了一個ComboBoxEdit控件,用於選擇該控件所綁定到的字段(前提是給 CtrlValidation類型中的DataSource何DataMember屬性賦過值,本類型中的 FillCombFiled方法會通過反射,獲取DataSet中DataTable的列,從而綁定到 Gridview中ComboBoxEdit控件的 Items屬性中)。

(2)窗體中定義了一個ArrayList類型的arrType,該ArrayList中存放的是控件 的類型,表名只對該類型的控件做處理,而其他類型的控件則不作處理。

(3)在FrmChoose有參構造函數中,會更具組件CtrlValidation的上下文,遍歷 窗體上的所有控件,並且將控件類型在arrType列表中的控件,添加到控件集合 control中。

實現效果如圖1示:

圖1

這種的實現方式,比較上篇blog的實現方式,更加的方便。在窗體設計時,將 CtrlValidation組件拖入,便會自動加載需要控制的控件(有arrType列表中的控 件類型決定)。在 CtrlValidation屬性中,設置集合屬性CtrlCollect,將會彈出 如圖1所示的畫面。點擊確定完成控制屬性的設置。再就可以調用該組件另外的8 個功能函數。

本篇blog主要是為了闡述如何開發組件,如何給組件定義可視的屬性,並且定 義集合屬性。但願我講清楚了。

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