这是本人自潜水以来,首次在blog首页上发表技术文章,本不是不乐意分享,而是有这样的念头:“我知道的大家都知道,我不知道的大家也都知道,还是不显眼了吧。”今天看到首页上 潇湘隐者 的一篇文章《WinForm 清空界面控件值的小技巧》,突然想到这东西我以前也做过,还是决定来显一下,提高一下知名度,就前来给大家分享一下,望各位多多指教。首先来说说本文所描述的东西有哪些功能:(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抽象类。
代码三(文本框对应的操作类)/// <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;
}
}代码四(ComboBox具体操作类)/// <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,Formate=""},
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个函数了,赶快动手,看看效果吧。
说明:这是一种封装形式,下次我会将ControlValidation类型封装成一个Component(组件)。这样用拖拽的方式在设计时供开发人员选择属性,使用起来会更加的方便。
该控件属本人原创,功能使用上没遇到什么问题,技术上的实现,各位大牛看了,不知道有什么建议给小弟,欢迎各位大牛多多提意见或建议!