代碼想要實現的功能是:
在沒有輸入文本時,能夠出現相應的提示;
輸入文本時,將提示文本隱藏掉。
實現原理:
一、繼承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++; } } } } }