代码想要实现的功能是:
在没有输入文本时,能够出现相应的提示;
输入文本时,将提示文本隐藏掉。
实现原理:
一、继承TextBox类,重写TextBox的三个事件(OnHandleCreated,OnTextChanged,OnGotFocus)
二、 不能直接在TextBoxChange中增加判断,容易频繁GDI绘图
三、 使用Timer进行延时GDI+,避免频繁绘图
代码实现:
先添加一个用户控件
将新建的UserControl继承TextBox
public partial class UserControl1 : TextBox
生成一个方法,实现当文本改变或焦点改变时判断文本长度,当Text.Length=0时,用GDI在TextBox上绘制显示需要的文本
int i = 0;
private void ReDraw(TextBox textBox) { Graphics g; g = Graphics.FromHwnd(textBox.Handle); if (textBox.Text.Length <= 0) { Font font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);//设置字体,大小,粗细 Brush sbrush = new SolidBrush(Color.Gray);//设置颜色 g.DrawString("请输入文本......", font, sbrush, 1, 1); g.Save(); i = 0; } else { if (i == 0) { g.Clear(textBox.BackColor); Font font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);//设置字体,大小,粗细 Brush sbrush = new SolidBrush(this.ForeColor);//设置颜色 g.DrawString(Text, font, sbrush, 0, 0); g.Save(); i++; } } }
之后我发现在触发OnTextChanged时直接在文本上面绘图,会导致界面无法更新到我需要显示的页面。
原因可能为触发OnTextChanged时,系统默认的GDI的绘图速度慢于我写的这个方法。
所以增加一个Timer,在文字发生改变时实现GDI延时绘图
public UserControl1() { InitializeComponent(); timer = new Timer(); timer.Interval = 30; timer.Tick += Timer_Tick; timer.Enabled = false; } private void Timer_Tick(object sender, EventArgs e) { ReDraw(this); timer.Enabled = false; }
最后将OnHandleCreated,OnTextChanged,OnGotFocus三个事件重写
OnHandleCreated实现文本框加载时,默认显示提示文本。
OnTextChanged实现文字改变时,判断是否显示提示文本。
OnGotFocus当TextBox窗体失去焦点后重新获得焦点时,显示提示文本。
protected override void OnHandleCreated(EventArgs e) { ReDraw(this); base.OnHandleCreated(e); } protected override void OnTextChanged(EventArgs e) { ReDraw(this); base.OnTextChanged(e); } protected override void OnGotFocus(EventArgs e) { ReDraw(this); base.OnGotFocus(e); }
该代码还有优化的空间,应该可以用其他的办法替代延时的方法。想到再补充。。
所有代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace TextBoxControler { public partial class UserControl1 : TextBox { private Timer timer; public UserControl1() { InitializeComponent(); timer = new Timer(); timer.Interval = 30; timer.Tick += Timer_Tick; timer.Enabled = false; } private void Timer_Tick(object sender, EventArgs e) { ReDraw(this); timer.Enabled = false; } protected override void OnHandleCreated(EventArgs e) { ReDraw(this); base.OnHandleCreated(e); } protected override void OnTextChanged(EventArgs e) { ReDraw(this); base.OnTextChanged(e); } protected override void OnGotFocus(EventArgs e) { ReDraw(this); base.OnGotFocus(e); } int i = 0; private void ReDraw(TextBox textBox) { Graphics g; g = Graphics.FromHwnd(textBox.Handle); if (textBox.Text.Length <= 0) { Font font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);//设置字体,大小,粗细 Brush sbrush = new SolidBrush(Color.Gray);//设置颜色 g.DrawString("请输入文本......", font, sbrush, 1, 1); g.Save(); i = 0; } else { if (i == 0) { g.Clear(textBox.BackColor); Font font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);//设置字体,大小,粗细 Brush sbrush = new SolidBrush(this.ForeColor);//设置颜色 g.DrawString(Text, font, sbrush, 0, 0); g.Save(); i++; } } } } }