Watermark TextBox in WinForms

前端 未结 10 1842
说谎
说谎 2020-11-22 00:35

Can anyone point me to a good implementation of a basic Windows Forms TextBox that will initially show watermark text that disappears when the cursor enters it? I think I ca

10条回答
  •  无人共我
    2020-11-22 01:23

    With .Net Core 3 a property was introduced into TextBox: PlaceHolderText

    If one is going to need this in a FrameWork application the required code parts can be taken from the official open source code and placed in a TextBox descendant (see license).

    This supports multiline TextBox and also RTL text.

    public class PlaceHolderTextBox : TextBox
    {
        private const int WM_KILLFOCUS = 0x0008;
        private const int WM_PAINT = 0x000F;
    
        private string _placeholderText;
    
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
    
            if (this.ShouldRenderPlaceHolderText(m))
            {
                using Graphics g = this.CreateGraphics();
                this.DrawPlaceholderText(g);
            }
        }
    
        #region PlaceHolder
    
        /// 
        ///  Gets or sets the text that is displayed when the control has no text and does not have the focus.
        /// 
        /// The text that is displayed when the control has no text and does not have the focus.
        [Localizable(true), DefaultValue("")]
        public virtual string PlaceholderText
        {
            get => _placeholderText;
            set
            {
                if (value == null)
                {
                    value = string.Empty;
                }
    
                if (_placeholderText != value)
                {
                    _placeholderText = value;
                    if (this.IsHandleCreated)
                    {
                        this.Invalidate();
                    }
                }
            }
        }
    
        //-------------------------------------------------------------------------------------------------
    
        /// 
        ///  Draws the  in the client area of the  using the default font and color.
        /// 
        private void DrawPlaceholderText(Graphics graphics)
        {
            TextFormatFlags flags = TextFormatFlags.NoPadding | TextFormatFlags.Top |
                                    TextFormatFlags.EndEllipsis;
            Rectangle rectangle = this.ClientRectangle;
    
            if (this.RightToLeft == RightToLeft.Yes)
            {
                flags |= TextFormatFlags.RightToLeft;
                switch (this.TextAlign)
                {
                    case HorizontalAlignment.Center:
                        flags |= TextFormatFlags.HorizontalCenter;
                        rectangle.Offset(0, 1);
                        break;
                    case HorizontalAlignment.Left:
                        flags |= TextFormatFlags.Right;
                        rectangle.Offset(1, 1);
                        break;
                    case HorizontalAlignment.Right:
                        flags |= TextFormatFlags.Left;
                        rectangle.Offset(0, 1);
                        break;
                }
            }
            else
            {
                flags &= ~TextFormatFlags.RightToLeft;
                switch (this.TextAlign)
                {
                    case HorizontalAlignment.Center:
                        flags |= TextFormatFlags.HorizontalCenter;
                        rectangle.Offset(0, 1);
                        break;
                    case HorizontalAlignment.Left:
                        flags |= TextFormatFlags.Left;
                        rectangle.Offset(1, 1);
                        break;
                    case HorizontalAlignment.Right:
                        flags |= TextFormatFlags.Right;
                        rectangle.Offset(0, 1);
                        break;
                }
            }
    
            TextRenderer.DrawText(graphics, this.PlaceholderText, this.Font, rectangle, SystemColors.GrayText, this.BackColor, flags);
        }
        
        private bool ShouldRenderPlaceHolderText(in Message m) =>
            !string.IsNullOrEmpty(this.PlaceholderText) &&
            (m.Msg == WM_PAINT || m.Msg == WM_KILLFOCUS) &&
            !this.GetStyle(ControlStyles.UserPaint) &&
            !this.Focused && this.TextLength == 0;
    
        #endregion
    }
    

提交回复
热议问题