官网

http://www.hzhcontrols.com

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 

idkey=6e08741ef16fe53bf0314c1c9e336c4f626047943a8b76bac062361bab6b4f8d">

目录

https://www.cnblogs.com/bfyx/p/11364884.html

准备工作

终于到文本框了,文本框将包含原文本框扩展,透明文本框,数字输入文本框,带边框文本框

本文将讲解原文本框扩展,主要增加水印和输入控制

开始

添加一个组件,命名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(, , , );
  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 = ;
  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() || e.KeyChar == System.Convert.ToChar())
  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 < )
  48. {
  49. num = ;
  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 == && !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(, , , );
  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 = ;
  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() || e.KeyChar == System.Convert.ToChar())
  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 < )
  233. {
  234. num = ;
  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 == && !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 == || m.Msg == || m.Msg == )
  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. }

用处及效果

用处:需要控制输入,需要显示水印

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧

(二十八)c#Winform自定义控件-文本框(一)的更多相关文章

  1. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  2. (十六)c#Winform自定义控件-文本框哪里去了?-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  3. (二十九)c#Winform自定义控件-文本框(二)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  4. (三十一)c#Winform自定义控件-文本框(四)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  5. (二十)c#Winform自定义控件-有后退的窗体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  6. NLP(二十八)多标签文本分类

      本文将会讲述如何实现多标签文本分类. 什么是多标签分类?   在分类问题中,我们已经接触过二分类和多分类问题了.所谓二(多)分类问题,指的是y值一共有两(多)个类别,每个样本的y值只能属于其中的一 ...

  7. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21我要评论 这篇文章主要介绍了Android项目 ...

  8. VMware vSphere 服务器虚拟化之二十八 桌面虚拟化之安装View传输服务器

    VMware vSphere 服务器虚拟化之二十八 桌面虚拟化之安装View传输服务器 View 传输服务器用于管理和简化数据中心与在最终用户本地系统上检出使用的 View 桌面之间的数据传输.必须安 ...

  9. (转载)Android项目实战(二十八):Zxing二维码实现及优化

    Android项目实战(二十八):Zxing二维码实现及优化   前言: 多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意. 当然,项目中 ...

随机推荐

  1. 控制反转&依赖注入

    IoC(Inversion of Control,控制反转).这是spring的核心,贯穿始终.所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系.这是什么 ...

  2. 洛谷 P2671 求和

    题目描述 一条狭长的纸带被均匀划分出了nn个格子,格子编号从11到nn.每个格子上都染了一种颜色color\_icolor_i用[1,m][1,m]当中的一个整数表示),并且写了一个数字number\ ...

  3. 网络IP的操作

    10.10.10.10/8求解问题:子网掩码 10.255.255.255该IP地址所在网络的网络ID 10.0.0.0该IP地址所在网络的广播地址 10.255.255.255该IP地址所在网络的I ...

  4. select模块(I/O多路复用)

    0709自我总结 select模块 一.介绍 Python中的select模块专注于I/O多路复用,提供了select poll epoll三个方法(其中后两个在Linux中可用,windows仅支持 ...

  5. 【Gym - 101002F】Mountain Scenes(dp)

    Mountain Scenes Descriptions 给你一个长度为n的丝带,一个宽w一个高h 的 格子,用丝带去填充格子,这填充后只需要满足至少有一列的丝带长度与其他格子不同即可.丝带可以不全部 ...

  6. Spring Cloud Config 实现配置中心,看这一篇就够了

    Spring Cloud Config 是 Spring Cloud 家族中最早的配置中心,虽然后来又发布了 Consul 可以代替配置中心功能,但是 Config 依然适用于 Spring Clou ...

  7. 学习16内容# 1.自定义模块 # 2.time # 3.datetime # 4.random

    模块的定义与分类 模块是什么? ​ 这几天,我们进入模块的学习.在学习模块之前,我们首先要知道,什么是模块? ​ 一个函数封装一个功能,你使用的软件可能就是由n多个函数组成的(先不考虑面向对象).比如 ...

  8. MySql 命令(命令行)

    1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...

  9. C#编程.面向对象编程.可删除对象(Using{})

    Using关键字可以在代码块中初始化使用重要资源的对象,Dispose()方法会在这个代码块的末尾自动调用,用法如下: <ClassName> <VariableName> = ...

  10. Java IO 为什么我们需要缓冲区

    在执行IO操作我们通常会设置一个字节数组作为缓冲区用来写/读数据,一般情况下一个合理大小的缓冲区是有利于提升性能的,但是有一个问题一直困扰着我,为什么缓冲区可以提升IO操作的性能? 经查阅资料之后,总 ...