前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
官网:https://www.hzhcontrols.cn
GitHub:https://github.com/kwwwvagaa/NetWinformControl
如果觉得写的还行,请点个 star 支持一下吧
目录
c#Winform自定义控件-目录_c#winform自定义控件-有图标的按钮-CSDN博客
准备工作
终于到文本框了,文本框将包含原文本框扩展,透明文本框,数字输入文本框,带边框文本框
本文将讲解原文本框扩展,主要增加水印和输入控制
开始
添加一个组件,命名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 }
下面是完整代码
// 版权所有 黄正辉 交流群:568015492 QQ:623128629
// 文件名称:TextBoxEx.cs
// 创建日期:2019-08-15 16:03:44
// 功能描述:TextBox
// 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace HZH_Controls.Controls
{
public partial class TextBoxEx : TextBox
{
private bool blnFocus = false;
private string _promptText = string.Empty;
private Font _promptFont = new Font("微软雅黑", 15f, FontStyle.Regular, GraphicsUnit.Pixel);
private Color _promptColor = Color.Gray;
private Rectangle _myRectangle = Rectangle.FromLTRB(1, 3, 1000, 3);
private TextInputType _inputType = TextInputType.NotControl;
private string _regexPattern = "";
private string m_strOldValue = string.Empty;
private decimal _maxValue = 1000000m;
private decimal _minValue = -1000000m;
private int _decLength = 2;
/// <summary>
/// 水印文字
/// </summary>
[Description("水印文字"), Category("自定义")]
public string PromptText
{
get
{
return this._promptText;
}
set
{
this._promptText = value;
this.OnPaint(null);
}
}
[Description("水印字体"), Category("自定义")]
public Font PromptFont
{
get
{
return this._promptFont;
}
set
{
this._promptFont = value;
}
}
[Description("水印颜色"), Category("自定义")]
public Color PromptColor
{
get
{
return this._promptColor;
}
set
{
this._promptColor = value;
}
}
public Rectangle MyRectangle
{
get;
set;
}
public string OldText
{
get;
set;
}
[Description("获取或设置一个值,该值指示文本框中的文本输入类型。")]
public TextInputType InputType
{
get
{
return this._inputType;
}
set
{
this._inputType = value;
if (value != TextInputType.NotControl)
{
TextChanged -= new EventHandler(this.TextBoxEx_TextChanged);
TextChanged += new EventHandler(this.TextBoxEx_TextChanged);
}
else
{
TextChanged -= new EventHandler(this.TextBoxEx_TextChanged);
}
}
}
/// <summary>
/// 获取或设置一个值,该值指示当输入类型InputType=Regex时,使用的正则表达式。
/// </summary>
[Description("获取或设置一个值,该值指示当输入类型InputType=Regex时,使用的正则表达式。")]
public string RegexPattern
{
get
{
return this._regexPattern;
}
set
{
this._regexPattern = value;
}
}
/// <summary>
/// 当InputType为数字类型时,能输入的最大值
/// </summary>
[Description("当InputType为数字类型时,能输入的最大值。")]
public decimal MaxValue
{
get
{
return this._maxValue;
}
set
{
this._maxValue = value;
}
}
/// <summary>
/// 当InputType为数字类型时,能输入的最小值
/// </summary>
[Description("当InputType为数字类型时,能输入的最小值。")]
public decimal MinValue
{
get
{
return this._minValue;
}
set
{
this._minValue = value;
}
}
/// <summary>
/// 当InputType为数字类型时,能输入的最小值
/// </summary>
[Description("当InputType为数字类型时,小数位数。")]
public int DecLength
{
get
{
return this._decLength;
}
set
{
this._decLength = value;
}
}
public TextBoxEx()
{
this.InitializeComponent();
base.GotFocus += new EventHandler(this.TextBoxEx_GotFocus);
base.MouseUp += new MouseEventHandler(this.TextBoxEx_MouseUp);
base.KeyPress += TextBoxEx_KeyPress;
}
void TextBoxEx_KeyPress(object sender, KeyPressEventArgs e)
{
//以下代码 取消按下回车或esc的“叮”声
if (e.KeyChar == System.Convert.ToChar(13) || e.KeyChar == System.Convert.ToChar(27))
{
e.Handled = true;
}
}
private void TextBoxEx_MouseUp(object sender, MouseEventArgs e)
{
if (this.blnFocus)
{
base.SelectAll();
this.blnFocus = false;
}
}
private void TextBoxEx_GotFocus(object sender, EventArgs e)
{
this.blnFocus = true;
base.SelectAll();
}
private void TextBoxEx_TextChanged(object sender, EventArgs e)
{
if (this.Text == "")
{
this.m_strOldValue = this.Text;
}
else if (this.m_strOldValue != this.Text)
{
if (!ControlHelper.CheckInputType(this.Text, this._inputType, this._maxValue, this._minValue, this._decLength, this._regexPattern))
{
int num = base.SelectionStart;
if (this.m_strOldValue.Length < this.Text.Length)
{
num--;
}
else
{
num++;
}
base.TextChanged -= new EventHandler(this.TextBoxEx_TextChanged);
this.Text = this.m_strOldValue;
base.TextChanged += new EventHandler(this.TextBoxEx_TextChanged);
if (num < 0)
{
num = 0;
}
base.SelectionStart = num;
}
else
{
this.m_strOldValue = this.Text;
}
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (string.IsNullOrEmpty(this.Text) && !string.IsNullOrEmpty(this._promptText))
{
if (e == null)
{
using (Graphics graphics = Graphics.FromHwnd(base.Handle))
{
if (this.Text.Length == 0 && !string.IsNullOrEmpty(this.PromptText))
{
TextFormatFlags textFormatFlags = TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter;
if (this.RightToLeft == RightToLeft.Yes)
{
textFormatFlags |= (TextFormatFlags.Right | TextFormatFlags.RightToLeft);
}
TextRenderer.DrawText(graphics, this.PromptText, this._promptFont, base.ClientRectangle, this._promptColor, textFormatFlags);
}
}
}
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 15 || m.Msg == 7 || m.Msg == 8)
{
this.OnPaint(null);
}
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
base.Invalidate();
}
}
}
用处及效果
用处:需要控制输入,需要显示水印