多年前写的文本框扩展控件(有ValueChanging事件等),已放github

来源:互联网 发布:php 点卡充值源码 编辑:程序博客网 时间:2024/05/29 10:44

本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作。

文章是哥(mephisto)写的,SourceLink

阅读目录

  • 介绍
  • 起因
  • 代码
  • 使用
  • GitHub

本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作。

文章是哥(mephisto)写的,SourceLink

 

介绍

    这个TextBoxEx控件是cs下的,为了广大的框架都能用,就基于Framework2.0,主要有原来的textbox的功能,然后追加了EditValueChanging,数字类型输入,最大值,最小值。大家可以看完后追加下功能,比如正则输入。

起因

 

      也是5年前的事情了,当时在做cs,一般cs都会用第三方控件,比如Dev等,dev中就有很多人性化的控件,比如我们用的比较多textbox,他就有EditValueChanging事件,当时我就想,不可能所以的小项目还要用到dev,那又想自己用到这么方便的控件怎么办,于是我就开始自己做了这个控件,抛砖引玉,只是丰富了一点,但确实对我那个年代的技术提高起了些许作用。

代码

  我们先看下项目结构,因为就一个扩展控件,所以整体上看,组织结构很简单。如图:

在ControlsEx这个工程中,主要一个自定义的事件所需参数ChangingEventArgs和一个扩展控件TextBoxEx

一:ChangingEventArgs:

     主要定义EditValueChanging所需的数据结构。

 1     /// <summary> 2     /// 正在改变EventArgs 3     /// </summary> 4     public class ChangingEventArgs : CancelEventArgs 5     { 6         private object newValue; 7         private object oldValue; 8  9         /// <summary>10         /// 正在改变EventArgs11         /// </summary>12         /// <param name="oldValue">原值</param>13         /// <param name="newValue">新值</param>14         public ChangingEventArgs(object oldValue, object newValue)15             : this(oldValue, newValue, false)16         {17         }18 19         /// <summary>20         /// 正在改变EventArgs21         /// </summary>22         /// <param name="oldValue">原值</param>23         /// <param name="newValue">新值</param>24         /// <param name="cancel">是否取消</param>25         public ChangingEventArgs(object oldValue, object newValue, bool cancel)26             : base(cancel)27         {28             this.oldValue = oldValue;29             this.newValue = newValue;30         }31 32         /// <summary>33         /// 新值34         /// </summary>35         public object NewValue36         {37             get38             {39                 return this.newValue;40             }41             set42             {43                 this.newValue = value;44             }45         }46 47         /// <summary>48         /// 原值49         /// </summary>50         public object OldValue51         {52             get53             {54                 return this.oldValue;55             }56         }57     }
View Code

二:TextBoxEx控件

     提供扩展的textbox功能。

1.委托及事件定义

     这里没有简单的用事件参数,还是使用了事件属性,大家如果感兴趣,可以去看下msdn对这两块的解释,也没用简单的使用Action,因为你设计的时候写的简单了,方便了,易用了,但是别人调用的时候就不简单,方便了。

 1         /// <summary> 2         /// 改变中事件句柄 3         /// </summary> 4         /// <param name="sender"></param> 5         /// <param name="e"></param> 6         public delegate void ChangingEventHandler(object sender, ChangingEventArgs e); 7  8         /// <summary> 9         /// <para>值改变中事件10         /// </para>11         /// </summary>12         [Description("值改变中事件"), Category("事件")]13         public event ChangingEventHandler EditValueChanging14         {15             add16             {17                 base.Events.AddHandler(editValueChanging, value);18             }19             remove20             {21                 base.Events.RemoveHandler(editValueChanging, value);22             }23         } 
View Code

2.设计器阶段的界面输入
     为了方便使用,就加入了设计器阶段属性,方便简单的输入。

 1         /// <summary> 2         /// 输入的最大值 3         /// </summary> 4         [Description("输入的最大值")] 5         public Int32 MaxNum 6         { 7             get { return _maxNum; } 8             set { _maxNum = value; } 9         }10         /// <summary>11         /// 输入的最小值12         /// </summary>13         [Description("输入的最小值")]14         public Int32 MinNum15         {16             get { return _minNum; }17             set18             {19                 if (value <= 0)20                     _minNum = value;21             }22         }23         /// <summary>24         /// 输入值类型25         /// </summary>26         [Description("输入值类型")]27         public ValueType EditValueType28         {29             get { return _editValueType; }30             set31             {32                 _editValueType = value;33                 //设置初始值34                 if (value == ValueType.Number)35                 {36                     EditValue = 0;37                 }38                 else39                     EditValue = null;40             }41         }
View Code

3.整体代码
   其实也没什么技术含量,只是提供个思路。

  1     public class TextBoxEx:TextBox  2     {  3         #region 委托  4         /// <summary>  5         /// 改变中事件句柄  6         /// </summary>  7         /// <param name="sender"></param>  8         /// <param name="e"></param>  9         public delegate void ChangingEventHandler(object sender, ChangingEventArgs e); 10         #endregion 11  12         #region 参数 13         private Int32 _maxNum = Int32.MaxValue;//最大值 14         private Int32 _minNum = Int32.MinValue;//最小值 15         private ValueType _editValueType = ValueType.String; 16         private static readonly object editValueChanging = new object();//EditValueChanging事件对应的Key 17         #endregion 18  19         #region Protected 参数 20         /// <summary> 21         /// 编制值 22         /// </summary> 23         protected object fEditValue = null; 24         /// <summary> 25         /// 编辑原始值 26         /// </summary> 27         protected object fOldEditValue = null;  28         #endregion 29  30         #region 公有属性 31         /// <summary> 32         /// 输入的最大值 33         /// </summary> 34         [Description("输入的最大值")] 35         public Int32 MaxNum 36         { 37             get { return _maxNum; } 38             set { _maxNum = value; } 39         } 40         /// <summary> 41         /// 输入的最小值 42         /// </summary> 43         [Description("输入的最小值")] 44         public Int32 MinNum 45         { 46             get { return _minNum; } 47             set 48             { 49                 if (value <= 0) 50                     _minNum = value; 51             } 52         } 53         /// <summary> 54         /// 输入值类型 55         /// </summary> 56         [Description("输入值类型")] 57         public ValueType EditValueType 58         { 59             get { return _editValueType; } 60             set 61             { 62                 _editValueType = value; 63                 //设置初始值 64                 if (value == ValueType.Number) 65                 { 66                     EditValue = 0; 67                 } 68                 else 69                     EditValue = null; 70             } 71         } 72       73         #endregion 74  75         #region 事件属性 76         /// <summary> 77         /// <para>值改变中事件 78         /// </para> 79         /// </summary> 80         [Description("值改变中事件"), Category("事件")] 81         public event ChangingEventHandler EditValueChanging 82         { 83             add 84             { 85                 base.Events.AddHandler(editValueChanging, value); 86             } 87             remove 88             { 89                 base.Events.RemoveHandler(editValueChanging, value); 90             } 91         }   92         #endregion 93  94         #region 私有属性 95         /// <summary> 96         /// 编辑值 97         /// </summary> 98         private object EditValue 99         {100             get { return fEditValue; }101             set102             {103                 if (EditValue == value) return;104                 OnEditValueChanging(new ChangingEventArgs(fEditValue, value));105                 this.Text = fEditValue == null ? null : fEditValue.ToString();106             }107         }108         #endregion109 110         #region 事件111         /// <summary>112         /// 编辑值正在改变事件113         /// </summary>114         /// <param name="e"></param>115         protected virtual void OnEditValueChanging(ChangingEventArgs e)116         {117             //调用注册的事件118             ReiseEditValueChanging(e);119 120             if (e.Cancel)//注册的事件取消 还原值121             {122                 fEditValue = e.OldValue;123                 return;124             }125 126             switch (_editValueType)127             {128                 case ValueType.Number://数值类型129                     {130                         if (e.NewValue != null && !string.IsNullOrEmpty(e.NewValue.ToString()))//非空值131                         {132                             int intNewNum = 0;133                             if (!Int32.TryParse(e.NewValue.ToString(), out intNewNum))//非数字134                             {135                                 string strOp = e.NewValue.ToString();136                                 //负号137                                 if (ParseValueIsMinus(strOp))138                                 {139                                     strOp = strOp.Replace("-", "");140 141                                     int tempMin = 0;142                                     if (Int32.TryParse(strOp, out tempMin))143                                     {144                                         if (tempMin > Math.Abs(MinNum + 1))145                                         {146                                             fEditValue = e.OldValue;147                                             return;148                                         }149                                     }150                                     else151                                     {152                                         fEditValue = e.OldValue;153                                         return;154                                     }155                                     strOp = "-" + strOp;156                                     fEditValue = strOp;157                                 }158                                 else if (strOp.Contains("-"))//多负号情况159                                 {160                                     strOp = strOp.Replace("-", "");161                                     int tempMax = 0;162                                     if (Int32.TryParse(strOp, out tempMax))163                                     {164                                         if (tempMax > MaxNum)165                                         {166                                             fEditValue = e.OldValue;167                                             return;168                                         }169                                     }170                                     else171                                     {172                                         fEditValue = e.OldValue;173                                         return;174                                     }175                                     fEditValue = strOp;176                                 }177                                 else178                                     fEditValue = e.OldValue;//还原179                                 return;180                             }181                             if (intNewNum > MaxNum182                                 || intNewNum < MinNum)//不在范围里的数据183                             {184                                 fEditValue = e.OldValue;185                                 return;186                             }187                             //同步设置新值188                             fEditValue = e.NewValue;189                         }190                         else191                         {192                             //同步设置新值(特殊)193                             fEditValue = 0;194                         }195                     } break;196                 case ValueType.String:197                     {198                         fEditValue = e.NewValue;199                     } break;200                 default:201                     {202                         fEditValue = e.NewValue;203                     } break;204 205             }206         }207 208         /// <summary>209         /// 值改变后事件210         /// </summary>211         /// <param name="e"></param>212         protected override void OnTextChanged(EventArgs e)213         {214             if (this.Text != null)215                 this.SelectionStart = this.Text.Length;216 217             if (this.Text.Equals(EditValue))218             {219                 return;220             }221 222             base.OnTextChanged(e);223             EditValue = this.Text;224         }225 226         /// <summary>227         /// 调用注册的事件228         /// </summary>229         /// <param name="e"></param>230         public void ReiseEditValueChanging(ChangingEventArgs e)231         {232             ChangingEventHandler handler = (ChangingEventHandler)this.Events[editValueChanging];233             if (handler != null) handler(this, e);234         }235         #endregion236 237         #region 内部方法238         /// <summary>239         /// 判断字符串是否是负数240         /// </summary>241         /// <param name="strOp"></param>242         /// <returns></returns>243         private bool ParseValueIsMinus(string strOp)244         {245             bool blReturn = false;246 247             int index = strOp.IndexOf('-');248             if (index >= 0)249             {250                 index = strOp.IndexOf('-', index + 1);251                 if (index < 0)252                     blReturn = true;253             }254             return blReturn;255         }256         #endregion257 258 259         #region 枚举260         /// <summary>261         /// 改变值类型262         /// </summary>263         public enum ValueType264         {265             Number,266             String,267         } 268         #endregion269     }270 }
View Code

 

使用

由于是控件,所以没有采用UnitTest方式,而是建立一个winfrom窗体进行测试。

定义2个控件

texBoxEx1 字符串输入

tbxBoxEx2 数字型输入,最小值-200,最大值200

代码做了简单过滤

 1         private void textBoxEx1_EditValueChanging(object sender, ControlsEx.ChangingEventArgs e) 2         { 3             //简单的过滤abc和100 4             if (e.NewValue.ToString() == "abc") 5                 e.Cancel = true; 6         } 7  8         private void textBoxEx2_EditValueChanging(object sender, ControlsEx.ChangingEventArgs e) 9         {10             //简单的过滤10011             int temp = (int)e.NewValue;12             if (temp == 100)13                 e.Cancel = true;14         }
View Code

测试结果如下:

对于tbxBoxEx1的输入abc,在输入c的时候就输入不进去了,换个d就可以输入进去了。

对于tbxBoxEx2,在输入-201的时候不能输入,201的时候也不能,100的时候也不能。由于验证机制是调用订阅的验证机制然后才是基类的验证机制,所以订阅的是做扩展用的。所以订阅的代码还是要做点异常处理,比如输入其他字符号。当时想的是默认情况下基类判断起作用,如果想做扩展,订阅这个事件,然后处理,但是现在过了这多年回来看,这块还是需要优化下,应该为了更方便的点,基类的判断应该是一直前的,这样可以少了很多异常判断,所以这里测试代码就简单的过滤100就行了,负数等的自行取消订阅事件里的代码。

GitHub

https://github.com/sinodzh/ControlsEx

本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作。

文章是哥(mephisto)写的,SourceLink

 

0 0
原创粉丝点击