(二十八)c#Winform自定义控件-文本框(一)
程序员文章站
2022-05-29 10:27:48
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 如果觉得写的还行,请点个 star 支持一下吧 欢迎前来交流探讨: 企鹅群568015492 目录 ......
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
开源地址:
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
目录
准备工作
终于到文本框了,文本框将包含原文本框扩展,透明文本框,数字输入文本框,带边框文本框
本文将讲解原文本框扩展,主要增加水印和输入控制
开始
添加一个组件,命名textboxex,继承textbox
属性
1 private bool blnfocus = false; 2 3 private string _prompttext = string.empty; 4 5 private font _promptfont = new font("微软雅黑", 15f, fontstyle.regular, graphicsunit.pixel); 6 7 private color _promptcolor = color.gray; 8 9 private rectangle _myrectangle = rectangle.fromltrb(1, 3, 1000, 3); 10 11 private textinputtype _inputtype = textinputtype.notcontrol; 12 13 private string _regexpattern = ""; 14 15 private string m_stroldvalue = string.empty; 16 17 private decimal _maxvalue = 1000000m; 18 19 private decimal _minvalue = -1000000m; 20 21 private int _declength = 2; 22 23 /// <summary> 24 /// 水印文字 25 /// </summary> 26 [description("水印文字"), category("自定义")] 27 public string prompttext 28 { 29 get 30 { 31 return this._prompttext; 32 } 33 set 34 { 35 this._prompttext = value; 36 this.onpaint(null); 37 } 38 } 39 40 [description("水印字体"), category("自定义")] 41 public font promptfont 42 { 43 get 44 { 45 return this._promptfont; 46 } 47 set 48 { 49 this._promptfont = value; 50 } 51 } 52 53 [description("水印颜色"), category("自定义")] 54 public color promptcolor 55 { 56 get 57 { 58 return this._promptcolor; 59 } 60 set 61 { 62 this._promptcolor = value; 63 } 64 } 65 66 public rectangle myrectangle 67 { 68 get; 69 set; 70 } 71 72 public string oldtext 73 { 74 get; 75 set; 76 } 77 78 [description("获取或设置一个值,该值指示文本框中的文本输入类型。")] 79 public textinputtype inputtype 80 { 81 get 82 { 83 return this._inputtype; 84 } 85 set 86 { 87 this._inputtype = value; 88 if (value != textinputtype.notcontrol) 89 { 90 textchanged -= new eventhandler(this.textboxex_textchanged); 91 textchanged += new eventhandler(this.textboxex_textchanged); 92 } 93 else 94 { 95 textchanged -= new eventhandler(this.textboxex_textchanged); 96 } 97 } 98 } 99 /// <summary> 100 /// 获取或设置一个值,该值指示当输入类型inputtype=regex时,使用的正则表达式。 101 /// </summary> 102 [description("获取或设置一个值,该值指示当输入类型inputtype=regex时,使用的正则表达式。")] 103 public string regexpattern 104 { 105 get 106 { 107 return this._regexpattern; 108 } 109 set 110 { 111 this._regexpattern = value; 112 } 113 } 114 /// <summary> 115 /// 当inputtype为数字类型时,能输入的最大值 116 /// </summary> 117 [description("当inputtype为数字类型时,能输入的最大值。")] 118 public decimal maxvalue 119 { 120 get 121 { 122 return this._maxvalue; 123 } 124 set 125 { 126 this._maxvalue = value; 127 } 128 } 129 /// <summary> 130 /// 当inputtype为数字类型时,能输入的最小值 131 /// </summary> 132 [description("当inputtype为数字类型时,能输入的最小值。")] 133 public decimal minvalue 134 { 135 get 136 { 137 return this._minvalue; 138 } 139 set 140 { 141 this._minvalue = value; 142 } 143 } 144 /// <summary> 145 /// 当inputtype为数字类型时,能输入的最小值 146 /// </summary> 147 [description("当inputtype为数字类型时,小数位数。")] 148 public int declength 149 { 150 get 151 { 152 return this._declength; 153 } 154 set 155 { 156 this._declength = value; 157 } 158 }
一些事件
1 void textboxex_keypress(object sender, keypresseventargs e) 2 { 3 //以下代码 取消按下回车或esc的“叮”声 4 if (e.keychar == system.convert.tochar(13) || e.keychar == system.convert.tochar(27)) 5 { 6 e.handled = true; 7 } 8 } 9 10 private void textboxex_mouseup(object sender, mouseeventargs e) 11 { 12 if (this.blnfocus) 13 { 14 base.selectall(); 15 this.blnfocus = false; 16 } 17 } 18 19 private void textboxex_gotfocus(object sender, eventargs e) 20 { 21 this.blnfocus = true; 22 base.selectall(); 23 } 24 25 private void textboxex_textchanged(object sender, eventargs e) 26 { 27 if (this.text == "") 28 { 29 this.m_stroldvalue = this.text; 30 } 31 else if (this.m_stroldvalue != this.text) 32 { 33 if (!controlhelper.checkinputtype(this.text, this._inputtype, this._maxvalue, this._minvalue, this._declength, this._regexpattern)) 34 { 35 int num = base.selectionstart; 36 if (this.m_stroldvalue.length < this.text.length) 37 { 38 num--; 39 } 40 else 41 { 42 num++; 43 } 44 base.textchanged -= new eventhandler(this.textboxex_textchanged); 45 this.text = this.m_stroldvalue; 46 base.textchanged += new eventhandler(this.textboxex_textchanged); 47 if (num < 0) 48 { 49 num = 0; 50 } 51 base.selectionstart = num; 52 } 53 else 54 { 55 this.m_stroldvalue = this.text; 56 } 57 } 58 }
重绘
1 protected override void onpaint(painteventargs e) 2 { 3 base.onpaint(e); 4 if (string.isnullorempty(this.text) && !string.isnullorempty(this._prompttext)) 5 { 6 if (e == null) 7 { 8 using (graphics graphics = graphics.fromhwnd(base.handle)) 9 { 10 if (this.text.length == 0 && !string.isnullorempty(this.prompttext)) 11 { 12 textformatflags textformatflags = textformatflags.endellipsis | textformatflags.verticalcenter; 13 if (this.righttoleft == righttoleft.yes) 14 { 15 textformatflags |= (textformatflags.right | textformatflags.righttoleft); 16 } 17 textrenderer.drawtext(graphics, this.prompttext, this._promptfont, base.clientrectangle, this._promptcolor, textformatflags); 18 } 19 } 20 } 21 } 22 }
下面是完整代码
1 // 版权所有 黄正辉 交流群:568015492 qq:623128629 2 // 文件名称:textboxex.cs 3 // 创建日期:2019-08-15 16:03:44 4 // 功能描述:textbox 5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 6 using system; 7 using system.collections.generic; 8 using system.componentmodel; 9 using system.diagnostics; 10 using system.drawing; 11 using system.linq; 12 using system.text; 13 using system.windows.forms; 14 15 namespace hzh_controls.controls 16 { 17 public partial class textboxex : textbox 18 { 19 private bool blnfocus = false; 20 21 private string _prompttext = string.empty; 22 23 private font _promptfont = new font("微软雅黑", 15f, fontstyle.regular, graphicsunit.pixel); 24 25 private color _promptcolor = color.gray; 26 27 private rectangle _myrectangle = rectangle.fromltrb(1, 3, 1000, 3); 28 29 private textinputtype _inputtype = textinputtype.notcontrol; 30 31 private string _regexpattern = ""; 32 33 private string m_stroldvalue = string.empty; 34 35 private decimal _maxvalue = 1000000m; 36 37 private decimal _minvalue = -1000000m; 38 39 private int _declength = 2; 40 41 /// <summary> 42 /// 水印文字 43 /// </summary> 44 [description("水印文字"), category("自定义")] 45 public string prompttext 46 { 47 get 48 { 49 return this._prompttext; 50 } 51 set 52 { 53 this._prompttext = value; 54 this.onpaint(null); 55 } 56 } 57 58 [description("水印字体"), category("自定义")] 59 public font promptfont 60 { 61 get 62 { 63 return this._promptfont; 64 } 65 set 66 { 67 this._promptfont = value; 68 } 69 } 70 71 [description("水印颜色"), category("自定义")] 72 public color promptcolor 73 { 74 get 75 { 76 return this._promptcolor; 77 } 78 set 79 { 80 this._promptcolor = value; 81 } 82 } 83 84 public rectangle myrectangle 85 { 86 get; 87 set; 88 } 89 90 public string oldtext 91 { 92 get; 93 set; 94 } 95 96 [description("获取或设置一个值,该值指示文本框中的文本输入类型。")] 97 public textinputtype inputtype 98 { 99 get 100 { 101 return this._inputtype; 102 } 103 set 104 { 105 this._inputtype = value; 106 if (value != textinputtype.notcontrol) 107 { 108 textchanged -= new eventhandler(this.textboxex_textchanged); 109 textchanged += new eventhandler(this.textboxex_textchanged); 110 } 111 else 112 { 113 textchanged -= new eventhandler(this.textboxex_textchanged); 114 } 115 } 116 } 117 /// <summary> 118 /// 获取或设置一个值,该值指示当输入类型inputtype=regex时,使用的正则表达式。 119 /// </summary> 120 [description("获取或设置一个值,该值指示当输入类型inputtype=regex时,使用的正则表达式。")] 121 public string regexpattern 122 { 123 get 124 { 125 return this._regexpattern; 126 } 127 set 128 { 129 this._regexpattern = value; 130 } 131 } 132 /// <summary> 133 /// 当inputtype为数字类型时,能输入的最大值 134 /// </summary> 135 [description("当inputtype为数字类型时,能输入的最大值。")] 136 public decimal maxvalue 137 { 138 get 139 { 140 return this._maxvalue; 141 } 142 set 143 { 144 this._maxvalue = value; 145 } 146 } 147 /// <summary> 148 /// 当inputtype为数字类型时,能输入的最小值 149 /// </summary> 150 [description("当inputtype为数字类型时,能输入的最小值。")] 151 public decimal minvalue 152 { 153 get 154 { 155 return this._minvalue; 156 } 157 set 158 { 159 this._minvalue = value; 160 } 161 } 162 /// <summary> 163 /// 当inputtype为数字类型时,能输入的最小值 164 /// </summary> 165 [description("当inputtype为数字类型时,小数位数。")] 166 public int declength 167 { 168 get 169 { 170 return this._declength; 171 } 172 set 173 { 174 this._declength = value; 175 } 176 } 177 178 public textboxex() 179 { 180 this.initializecomponent(); 181 base.gotfocus += new eventhandler(this.textboxex_gotfocus); 182 base.mouseup += new mouseeventhandler(this.textboxex_mouseup); 183 base.keypress += textboxex_keypress; 184 } 185 186 void textboxex_keypress(object sender, keypresseventargs e) 187 { 188 //以下代码 取消按下回车或esc的“叮”声 189 if (e.keychar == system.convert.tochar(13) || e.keychar == system.convert.tochar(27)) 190 { 191 e.handled = true; 192 } 193 } 194 195 private void textboxex_mouseup(object sender, mouseeventargs e) 196 { 197 if (this.blnfocus) 198 { 199 base.selectall(); 200 this.blnfocus = false; 201 } 202 } 203 204 private void textboxex_gotfocus(object sender, eventargs e) 205 { 206 this.blnfocus = true; 207 base.selectall(); 208 } 209 210 private void textboxex_textchanged(object sender, eventargs e) 211 { 212 if (this.text == "") 213 { 214 this.m_stroldvalue = this.text; 215 } 216 else if (this.m_stroldvalue != this.text) 217 { 218 if (!controlhelper.checkinputtype(this.text, this._inputtype, this._maxvalue, this._minvalue, this._declength, this._regexpattern)) 219 { 220 int num = base.selectionstart; 221 if (this.m_stroldvalue.length < this.text.length) 222 { 223 num--; 224 } 225 else 226 { 227 num++; 228 } 229 base.textchanged -= new eventhandler(this.textboxex_textchanged); 230 this.text = this.m_stroldvalue; 231 base.textchanged += new eventhandler(this.textboxex_textchanged); 232 if (num < 0) 233 { 234 num = 0; 235 } 236 base.selectionstart = num; 237 } 238 else 239 { 240 this.m_stroldvalue = this.text; 241 } 242 } 243 } 244 245 protected override void onpaint(painteventargs e) 246 { 247 base.onpaint(e); 248 if (string.isnullorempty(this.text) && !string.isnullorempty(this._prompttext)) 249 { 250 if (e == null) 251 { 252 using (graphics graphics = graphics.fromhwnd(base.handle)) 253 { 254 if (this.text.length == 0 && !string.isnullorempty(this.prompttext)) 255 { 256 textformatflags textformatflags = textformatflags.endellipsis | textformatflags.verticalcenter; 257 if (this.righttoleft == righttoleft.yes) 258 { 259 textformatflags |= (textformatflags.right | textformatflags.righttoleft); 260 } 261 textrenderer.drawtext(graphics, this.prompttext, this._promptfont, base.clientrectangle, this._promptcolor, textformatflags); 262 } 263 } 264 } 265 } 266 } 267 268 protected override void wndproc(ref message m) 269 { 270 base.wndproc(ref m); 271 if (m.msg == 15 || m.msg == 7 || m.msg == 8) 272 { 273 this.onpaint(null); 274 } 275 } 276 277 protected override void ontextchanged(eventargs e) 278 { 279 base.ontextchanged(e); 280 base.invalidate(); 281 } 282 } 283 }
用处及效果
用处:需要控制输入,需要显示水印
最后的话
如果你喜欢的话,请到 点个星 星吧