您的位置:首页 > 产品设计 > UI/UE

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

2016-01-24 15:28 766 查看
本文版权归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         /// 正在改变EventArgs
11         /// </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         /// 正在改变EventArgs
21         /// </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 NewValue
36         {
37             get
38             {
39                 return this.newValue;
40             }
41             set
42             {
43                 this.newValue = value;
44             }
45         }
46
47         /// <summary>
48         /// 原值
49         /// </summary>
50         public object OldValue
51         {
52             get
53             {
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 EditValueChanging
14         {
15             add
16             {
17                 base.Events.AddHandler(editValueChanging, value);
18             }
19             remove
20             {
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 MinNum
15         {
16             get { return _minNum; }
17             set
18             {
19                 if (value <= 0)
20                     _minNum = value;
21             }
22         }
23         /// <summary>
24         /// 输入值类型
25         /// </summary>
26         [Description("输入值类型")]
27         public ValueType EditValueType
28         {
29             get { return _editValueType; }
30             set
31             {
32                 _editValueType = value;
33                 //设置初始值
34                 if (value == ValueType.Number)
35                 {
36                     EditValue = 0;
37                 }
38                 else
39                     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             set
102             {
103                 if (EditValue == value) return;
104                 OnEditValueChanging(new ChangingEventArgs(fEditValue, value));
105                 this.Text = fEditValue == null ? null : fEditValue.ToString();
106             }
107         }
108         #endregion
109
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                                     else
151                                     {
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                                     else
171                                     {
172                                         fEditValue = e.OldValue;
173                                         return;
174                                     }
175                                     fEditValue = strOp;
176                                 }
177                                 else
178                                     fEditValue = e.OldValue;//还原
179                                 return;
180                             }
181                             if (intNewNum > MaxNum
182                                 || intNewNum < MinNum)//不在范围里的数据
183                             {
184                                 fEditValue = e.OldValue;
185                                 return;
186                             }
187                             //同步设置新值
188                             fEditValue = e.NewValue;
189                         }
190                         else
191                         {
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         #endregion
236
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         #endregion
257
258
259         #region 枚举
260         /// <summary>
261         /// 改变值类型
262         /// </summary>
263         public enum ValueType
264         {
265             Number,
266             String,
267         }
268         #endregion
269     }
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             //简单的过滤100
11             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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: