首先來說說本文所描述的東西有哪些功能:
(1)在界面上輸入某個值之前,其他的控件都處於不可用狀態。
(2)需檢驗必填項是否為空。
(3)需檢驗用戶輸入的格式是否正確。
(4)清除控件內容。
(5)為控件設置默認值。
(6)清除清除錯誤提示信息(ErrorText)。
(7)將數據行的值映射到文本編輯框中。
(8)將編輯框中的數據賦給數據行。
看看我是怎麼實現的
【1】定義"設置條件"的實體類
代碼一
/// <summary>
/// 設置條件
/// </summary>
public class SetControl
{
/// <summary>
/// 控件名稱
/// </summary>
[Description("控件名稱")]
public object ControlName
{
get;
set;
}
/// <summary>
/// 是否可為空
/// </summary>
[Description("可否為空")]
public bool NullAble
{
get;
set;
}
/// <summary>
/// 默認值
/// </summary>
[Description("默認值")]
public object Default
{
get;
set;
}
/// <summary>
/// 匹配格式
/// </summary>
[Description("匹配格式")]
public string Formate
{
get;
set;
}
/// <summary>
/// 是否主鍵
/// </summary>
[Description("是否主鍵")]
public bool KeyFiled
{
get;
set;
}
/// <summary>
/// 對應字段的名稱
/// </summary>
[Description("對應字段的名稱")]
public string FiledName
{
get;
set;
}
/// <summary>
/// 重寫Tostring()方法。返回控件的名稱
/// </summary>
/// <returns></returns>
public override string ToString()
{
Type t = ControlName.GetType();
System.Reflection.PropertyInfo x = t.GetProperty("Name");
object cnm = x.GetValue(ControlName, null);
return cnm == DBNull.Value ? "" : cnm.ToString();
}
}
【2】定義一個抽象類,提供滿足以上所述的8個功能函數。
代碼二
/// <summary>
/// 不同控件的操作接口
/// 子類命名規則,控件的基本類型+Process
/// </summary>
public abstract class TypeProcess
{
protected SetControl _setCtrl;
protected TypeProcess(SetControl sender)
{
this._setCtrl = sender;
}
/// <summary>
/// 驗證必填項是否為空
/// </summary>
/// <returns></returns>
public abstract bool CheckNull();
/// <summary>
/// 驗證格式
/// </summary>
/// <returns></returns>
public abstract bool CheckFormate();
/// <summary>
/// 清除畫面
/// </summary>
public abstract void SetCtrlClear();
/// <summary>
/// 設置控件可用狀態
/// </summary>
public abstract void SetCtrlEnable(bool enable);
/// <summary>
/// 設置控件默認值
/// </summary>
public abstract void SetCtrlDefault();
/// <summary>
/// 清除錯誤提示信息
/// </summary>
public abstract void ClearErrText();
/// <summary>
/// 映射數據到編輯框
/// </summary>
public abstract void LoadToText(DataRow row);
/// <summary>
/// 將編輯框中的值賦給編輯行
/// </summary>
/// <param name="row"></param>
public abstract void SetTextToRow(DataRow row);
}
【3】具體控件(以下只具體實現TextBox和ComboBox兩個控件,其他的控件類 似,這裡就不細說)的具體操作方法,繼承自TypeProcess抽象類。
(1)TextBoxEdit控件(Dev控件)實現方法
代碼三
/// <summary>
/// 文本框對應的操作
/// </summary>
public class TextEditProcess : TypeProcess
{
DevExpress.XtraEditors.TextEdit txt;
public TextEditProcess(SetControl sender)
: base(sender)
{
txt = _setCtrl.ControlName as DevExpress.XtraEditors.TextEdit;
}
public override bool CheckNull()
{
if (!_setCtrl.NullAble)
{
if (txt.Text.Trim().Length == 0)
{
txt.ErrorText = "不能為 空";
txt.Focus();
return false;
}
}
return true;
}
public override bool CheckFormate()
{
string txtvalue = txt.Text;
string pattern = String.Format("^{0}$", _setCtrl.Formate);
if (!string.IsNullOrEmpty(_setCtrl.Formate) && !Regex.IsMatch(txtvalue, @pattern))
{
txt.ErrorText = "輸入的格式不正 確";
txt.Focus();
return false;
}
return true;
}
public override void SetCtrlClear()
{
txt.EditValue = null;
}
public override void SetCtrlEnable(bool enable)
{
if (_setCtrl.KeyFiled)
{
txt.Enabled = enable;
}
else
txt.Enabled = !enable;
}
public override void SetCtrlDefault()
{
txt.EditValue = _setCtrl.Default;
}
public override void ClearErrText()
{
txt.ErrorText = string.Empty;
}
public override void LoadToText(DataRow row)
{
if (0 != _setCtrl.FiledName.Trim ().Length)
txt.EditValue = row [_setCtrl.FiledName];
}
public override void SetTextToRow(DataRow row)
{
if (0 != _setCtrl.FiledName.Trim ().Length)
row[_setCtrl.FiledName] = txt.EditValue;
}
}
(2)ComboBoxEdit控件(Dev控件)實現方法
代碼四
/// <summary>
/// ComboBoxEdit控件操作
/// </summary>
public class ComboBoxEditProcess : TypeProcess
{
DevExpress.XtraEditors.ComboBoxEdit comb;
public ComboBoxEditProcess(SetControl sender)
: base(sender)
{
comb = _setCtrl.ControlName as DevExpress.XtraEditors.ComboBoxEdit;
}
public override bool CheckNull()
{
if (!_setCtrl.NullAble)
{
if (comb.EditValue == null)
{
comb.ErrorText = "不能為空 ";
comb.Focus();
return false;
}
}
return true;
}
public override bool CheckFormate()
{
return true;
}
public override void SetCtrlClear()
{
comb.EditValue = null;
}
public override void SetCtrlEnable(bool enable)
{
if (_setCtrl.KeyFiled)
{
comb.Enabled = enable;
}
else
comb.Enabled = !enable;
}
public override void SetCtrlDefault()
{
comb.EditValue = _setCtrl.Default;
}
public override void ClearErrText()
{
comb.ErrorText = string.Empty;
}
public override void LoadToText(DataRow row)
{
if (0 != _setCtrl.FiledName.Trim ().Length)
comb.EditValue = row [_setCtrl.FiledName];
}
public override void SetTextToRow(DataRow row)
{
if (0 != _setCtrl.FiledName.Trim ().Length)
row[_setCtrl.FiledName] = comb.EditValue;
}
}
【4】使用反射工廠,得到具體的控件操作類。
代碼五
/// <summary>
/// 抽象工廠,創建具體的操作類的對象
/// </summary>
public class TypeFactory
{
/// <summary>
/// 返回具體類型
/// </summary>
/// <param name="type"></param>
/// <param name="obj"></param>
/// <param name="ctrlCnm"></param>
/// <param name="validate"></param>
/// <returns></returns>
public static TypeProcess CreateType(string type, object[] obj, string ctrlCnm, TypeCache validate)
{
TypeProcess process;
if (validate.ExistObject(ctrlCnm))
process = validate.GetObject (ctrlCnm) as TypeProcess;
else
{
process = (TypeProcess) Assembly.Load("RealSailing.BizControls").CreateInstance(String.Format ("RealSailing.UI.Utils.{0}Process", type), false, BindingFlags.Default,
null, obj, new CultureInfo("zh-CN", false), new object[] { });
validate.AddObject(ctrlCnm, process);
}
return process;
}
}
【5】如果界面上控件數量頗多,避免反復的創建具體控件操作類的實例,使 用了緩存。
代碼六
/// <summary>
/// 對象緩存類
/// </summary>
public class TypeCache
{
private Hashtable htObj;
public TypeCache()
{
htObj = Hashtable.Synchronized(new Hashtable());
}
/// <summary>
/// 添加新對象實例
/// </summary>
/// <param name="name"></param>
/// <param name="instance"></param>
public void AddObject(string name, Object instance)
{
if (!htObj.ContainsKey(name))
htObj.Add(name, instance);
}
/// <summary>
/// 刪除對象實例
/// </summary>
/// <param name="name"></param>
public void DeleteObject(string name)
{
if (htObj.ContainsKey(name))
htObj.Remove(name);
}
/// <summary>
/// 獲取對應的對象
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public object GetObject(string name)
{
if (htObj.ContainsKey(name))
{
return htObj[name];
}
return null;
}
/// <summary>
/// 對象是否存在
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public bool ExistObject(string name)
{
return htObj.ContainsKey(name);
}
/// <summary>
/// 清除所有對象實例
/// </summary>
public void ClearObject()
{
htObj.Clear();
}
}
到此,就封裝了一些功能函數的操作,繼續看如何來使用他們.
封裝一個用於對窗體上的控件驗證的通用類,供外部調用。此類提供一個 List<SetControl> 類型的屬性,以及8個功能函數的方法。
代碼七
/// <summary>
/// 用於對窗體上的控件驗證的通用類
/// 如果控件在現有的類中不存在,請在 RealSailing.UI.Utils.CtrlValidate中添加類
/// 類名:完整的控件類型+Process;
/// 並繼承自TypeProcess
/// </summary>
public class ControlValidation
{
TypeCache typeCache;
public ControlValidation()
{
typeCache = new TypeCache();
}
List<SetControl> ctrlCollect = new List<SetControl>();
/// <summary>
/// 設置項集合
/// </summary>
public List<SetControl> CtrlCollect
{
get
{
return ctrlCollect;
}
set
{
ctrlCollect = value;
}
}
#region 提供方法
/// <summary>
/// 必填項是否為空,true表示不為空,FALSE表示為空
/// </summary>
/// <returns></returns>
public bool CheckIsNull()
{
foreach (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 (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
}
到此為止,我們已經封裝了一個很完整功能的類型,該類型包括開頭處提出的 8個功能函數,很方便的控制界面上控件的行為。
最後,我們來看看如何使用這個封裝類。
代碼八
/// <summary>
/// 初始控件集合
/// </summary>
void Init()
{
List<SetControl> controls = new List<SetControl>
{
new SetControl {ControlName=CombRegionType,FiledName= “MSTM030_REGIONTYPE”,Default=null,KeyFiled=true,NullAble=false,Format e=""},
new SetControl {ControlName=txtRegionCd,FiledName= “MSTM030_REGIONCD”,Default=null,KeyFiled=true,NullAble=false,Formate= ""},
new SetControl {ControlName=CombCompanyId,FiledName= “MSTM030_COMID”,Default=null,KeyFiled=false,NullAble=true,Formate=""} ,
}
validate.CtrlCollect = controls;
}
將Init()方法放到Load()或者是窗體的構造函數之下裡執行。當然,我們得 先創建實例ControlValidation validate = new ControlValidation();
好了,我們就可以在該頁面的任何地方執行上面的8個函數 (validate.SetCtrlClear()……)了,趕快動手,看看效果吧。
說明:這是一種封裝形式,下次我會將ControlValidation類型封裝成一個 Component(組件)。這樣用拖拽的方式在設計時供開發人員選擇屬性,使用起來 會更加的方便。
該控件屬本人原創,功能使用上沒遇到什麼問題,技術上的實現,各位大牛看 了,不知道有什麼建議給小弟,歡迎各位大牛多多提意見或建議!