导航

这是本人自潜水以来,首次在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(组件)。这样用拖拽的方式在设计时供开发人员选择属性,使用起来会更加的方便。

该控件属本人原创,功能使用上没遇到什么问题,技术上的实现,各位大牛看了,不知道有什么建议给小弟,欢迎各位大牛多多提意见或建议!