效果:
描述:
類似html標簽里input標簽里的placeHolder屬性,控件繼承TextBox,擁有一個描述提示信息的字段_txtPlaceHolder,重寫了消息處理函數WndProc,如果windows送出來的消息是繪制控件,就開始繪制,這里要注意的是TxtPlaceHolder的Set方法里的this.Invalidate();這個是如果控件繪制失敗,將重繪繪制,如果沒有這句代碼,拖動這個控件到窗體上,控件會報異常。
異常:
原因:
經過我的實驗,我發現只要為_txtPlaceHolder這個字段賦個不為null的初始值后去掉”this.Invalidate();“這句,程式也能運行。原因是_txtPlaceHolder.Length > 0
代碼:
public sealed class MyCustomTextBox:TextBox
{
private const int WM_PAINT = 0x000F;
private string _txtPlaceHolder="";
[Category("自定義屬性"), Description("文本框里的提示文字"), DefaultValue("請在此輸入"), Browsable(true)]
public string TxtPlaceHolder
{
get { return _txtPlaceHolder; }
set {
if (value == null) throw new ArgumentNullException("value");
_txtPlaceHolder = value;
this.Invalidate();
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_PAINT && !this.Focused && (this.TextLength == 0) && (_txtPlaceHolder.Length > 0))
{
TextFormatFlags tff = (TextFormatFlags.EndEllipsis |
TextFormatFlags.NoPrefix |
TextFormatFlags.Left |
TextFormatFlags.Top | TextFormatFlags.NoPadding);
using (Graphics g = this.CreateGraphics())
{
Rectangle rect = this.ClientRectangle;
rect.Offset(4, 1);
TextRenderer.DrawText(g, _txtPlaceHolder, this.Font, rect, SystemColors.GrayText, tff);
}
}
}
}
