方法一:

public partial class WaterTextBox : TextBox
   {
       private readonly Label lblwaterText = new Label();

       public WaterTextBox()
       {
           InitializeComponent();
           lblwaterText.BorderStyle = BorderStyle.None;
           lblwaterText.Enabled = false;
           lblwaterText.BackColor = Color.White;
           lblwaterText.AutoSize = false;
           lblwaterText.Top = 1;
           lblwaterText.Left = 0;
           Controls.Add(lblwaterText);
       }

       [Category("扩展属性"), Description("显示的提示信息")]
       public string WaterText
       {
           get { return lblwaterText.Text; }
           set { lblwaterText.Text = value; }
       }

       public override string Text
       {
           set
           {
               if (value != string.Empty)
                   lblwaterText.Visible = false;
               else
                   lblwaterText.Visible = true;
               base.Text = value;
           }
           get { return base.Text; }
       }

       protected override void OnSizeChanged(EventArgs e)
       {
           if (Multiline && (ScrollBars == ScrollBars.Vertical || ScrollBars == ScrollBars.Both))
               lblwaterText.Width = Width - 20;
           else
               lblwaterText.Width = Width;
           lblwaterText.Height = Height - 2;
           base.OnSizeChanged(e);
       }

       protected override void OnEnter(EventArgs e)
       {
           lblwaterText.Visible = false;
           base.OnEnter(e);
       }

       protected override void OnLeave(EventArgs e)
       {
           if (base.Text == string.Empty)
               lblwaterText.Visible = true;
           base.OnLeave(e);
       }
   }

方法二:(待改进)改进点:提示文本是颜色,进入时自动消失,失去焦点后如果没有值又显示提示文本。如果哪位改进好了,可以回给我看看吗?

public partial class WaterTextBox1 : TextBox
    {
        private String strEmptyValue = String.Empty;

        public WaterTextBox1()
        {
            InitializeComponent();
            processDefaultValue();
        }

        public String EmptyValue //记录空值的表现
        {
            get { return strEmptyValue; }
            set
            {
                if (base.Text == strEmptyValue)
                    base.Text = value.Trim();
                strEmptyValue = value.Trim();
                processDefaultValue();
            }
        }

        public override string Text //覆盖Text属性
        {
            get { return base.Text.Trim() == strEmptyValue.Trim() ? String.Empty : base.Text.Trim(); }
            set
            {
                base.Text = value;
                processDefaultValue();
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);
            processDefaultValue();
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
            if (base.Text == strEmptyValue)
            {
                SelectAll();
            }

        }

        protected override void OnValidating(CancelEventArgs e) //覆盖TextBox验证处理
        {
            processDefaultValue();
            base.OnValidating(e);
        }

        private void processDefaultValue() //处理表现空值的方法
        {
            base.Text = base.Text.Trim().Length <= 0 ? strEmptyValue : base.Text.Trim();
        }
    }