C# Winform 自定义控件——TextBox

效果:
 
描述:
类似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);
                }
            }
        }
    }

  


 
 
posted @ 2019-08-01 22:21 HelloLLLLL 阅读(...) 评论(...) 编辑 收藏