Watermark TextBox in WinForms

前端 未结 10 1840
说谎
说谎 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 00:58

    You can add a watermark to a Textbox (multiline or not) that works pretty well by drawing it in different controls Paint event. For Example:

        Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
            If TextBox1.Text = "" Then
                TextBox1.CreateGraphics.DrawString("Enter Text Here", Me.Font, New SolidBrush(Color.LightGray), 0, 0)
            End If
        End Sub
    

    -OO-

    0 讨论(0)
  • 2020-11-22 01:00

    The official term is "cue banner". Here's another way to do it, just inheriting TextBox gets the job done too. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox and set the Cue property.

    You get a live preview of the Cue value in the designer, localized to the form's Language property. Lots of bang for very little buck, an excellent demonstration of the good parts of Winforms.

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    class CueTextBox : TextBox {
        [Localizable(true)]
        public string Cue {
            get { return mCue; }
            set { mCue = value; updateCue(); }
        }
    
        private void updateCue() {
            if (this.IsHandleCreated && mCue != null) {
                SendMessage(this.Handle, 0x1501, (IntPtr)1, mCue);
            }
        }
        protected override void OnHandleCreated(EventArgs e) {
            base.OnHandleCreated(e);
            updateCue();
        }
        private string mCue;
    
        // PInvoke
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, string lp);
    }
    
    0 讨论(0)
  • 2020-11-22 01:01

    .NET Framework

    Here is an implementation of a TextBox which supports showing hint (or watermark or cue):

    • It also shows the hint when MultiLine is true.
    • It's based on handling WM_PAINT message and drawing the hint. So you can simply customize the hint and add some properties like hint color, or you can draw it right to left or control when to show the hint.
    using System.Drawing;
    using System.Windows.Forms;
    public class ExTextBox : TextBox
    {
        string hint;
        public string Hint
        {
            get { return hint; }
            set { hint = value; this.Invalidate(); }
        }
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == 0xf)
            {
                if (!this.Focused && string.IsNullOrEmpty(this.Text)
                    && !string.IsNullOrEmpty(this.Hint))
                {
                    using (var g = this.CreateGraphics())
                    {
                        TextRenderer.DrawText(g, this.Hint, this.Font,
                            this.ClientRectangle, SystemColors.GrayText , this.BackColor, 
                            TextFormatFlags.Top | TextFormatFlags.Left);
                    }
                }
            }
        }
    }
    

    If you use EM_SETCUEBANNER, then there will be 2 issues. The text always will be shown in a system default color. Also the text will not be shown when the TextBox is MultiLine.

    Using the painting solution, you can show the text with any color that you want. You also can show the watermark when the control is multi-line:

    Download

    You can clone or download the working example:

    • Download Zip
    • Github repository

    .NET CORE - TextBox.PlaceholderText

    The same approach has been used in .NET CORE implementation of TextBox and in Windows Forms .NET CORE, you can use PlaceholderText property.

    It supports both multi-line and single-line text-box.

    0 讨论(0)
  • 2020-11-22 01:08

    I wrote a reusable custom control class for my project.
    maybe it can help someone that need to implement multiple placeholder textboxes in his project. here is the C# and vb.net versions:

    C#:

    namespace reusebleplaceholdertextbox
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                // implementation
                CustomPlaceHolderTextbox myCustomTxt = new CustomPlaceHolderTextbox(
                    "Please Write Text Here...", Color.Gray, new Font("ARIAL", 11, FontStyle.Italic)
                    , Color.Black, new Font("ARIAL", 11, FontStyle.Regular)
                    );
    
                myCustomTxt.Multiline = true;
                myCustomTxt.Size = new Size(200, 50);
                myCustomTxt.Location = new Point(10, 10);
                this.Controls.Add(myCustomTxt);
            }
        }
    
        class CustomPlaceHolderTextbox : System.Windows.Forms.TextBox
        {
            public string PlaceholderText { get; private set; }
            public Color PlaceholderForeColor { get; private set; }
            public Font PlaceholderFont { get; private set; }
    
            public Color TextForeColor { get; private set; }
            public Font TextFont { get; private set; }
    
            public CustomPlaceHolderTextbox(string placeholdertext, Color placeholderforecolor,
                Font placeholderfont, Color textforecolor, Font textfont)
            {
                this.PlaceholderText = placeholdertext;
                this.PlaceholderFont = placeholderfont;
                this.PlaceholderForeColor = placeholderforecolor;
                this.PlaceholderFont = placeholderfont;
                this.TextForeColor = textforecolor;
                this.TextFont = textfont;
                if (!string.IsNullOrEmpty(this.PlaceholderText))
                {
                    SetPlaceHolder(true);
                    this.Update();
                }
            }
    
            private void SetPlaceHolder(bool addEvents)
            {
                if (addEvents)
                {  
                    this.LostFocus += txt_lostfocus;
                    this.Click += txt_click;
                }
    
                this.Text = PlaceholderText;
                this.ForeColor = PlaceholderForeColor;
                this.Font = PlaceholderFont;
            }
    
            private void txt_click(object sender, EventArgs e)
            {
                // IsNotFirstClickOnThis:
                // if there is no other control in the form
                // we will have a problem after the first load
                // because we dont other focusable control to move the focus to
                // and we dont want to remove the place holder
                // only on first time the place holder will be removed by click event
                RemovePlaceHolder();
                this.GotFocus += txt_focus;
                // no need for this event listener now
                this.Click -= txt_click;
            }
    
            private void RemovePlaceHolder()
            {
                this.Text = "";
                this.ForeColor = TextForeColor;
                this.Font = TextFont;
            }
            private void txt_lostfocus(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(this.Text))
                {
                    // set placeholder again
                    SetPlaceHolder(false);
                }
            }
    
            private void txt_focus(object sender, EventArgs e)
            {
                if (this.Text == PlaceholderText)
                {
                    // IsNotFirstClickOnThis:
                    // if there is no other control in the form
                    // we will have a problem after the first load
                    // because we dont other focusable control to move the focus to
                    // and we dont want to remove the place holder
                    RemovePlaceHolder();
                }
            }
        }
    }
    


    VB.NET:


    Namespace CustomControls
    
        Public Class PlaceHolderTextBox
            Inherits System.Windows.Forms.TextBox
    
            Public Property PlaceholderText As String
            Public Property PlaceholderForeColor As Color
            Public Property PlaceholderFont As Font
            Public Property TextForeColor As Color
            Public Property TextFont As Font
    
            Public Sub New(ByVal placeholdertext As String, ByVal placeholderforecolor As Color, ByVal placeholderfont As Font, ByVal txtboxbackcolor As Color, ByVal textforecolor As Color, ByVal textfont As Font)
                Me.PlaceholderText = placeholdertext
                Me.PlaceholderFont = placeholderfont
                Me.PlaceholderForeColor = placeholderforecolor
                Me.PlaceholderFont = placeholderfont
                Me.TextForeColor = textforecolor
                Me.TextFont = textfont
                Me.BackColor = txtboxbackcolor
                If Not String.IsNullOrEmpty(Me.PlaceholderText) Then
                    SetPlaceHolder(True)
                    Me.Update()
                End If
            End Sub
    
            Private Sub SetPlaceHolder(ByVal addEvents As Boolean)
                If addEvents Then
                    AddHandler Me.LostFocus, AddressOf txt_lostfocus
                    AddHandler Me.Click, AddressOf txt_click
                End If
    
                Me.Text = PlaceholderText
                Me.ForeColor = PlaceholderForeColor
                Me.Font = PlaceholderFont
            End Sub
    
            Private Sub txt_click(ByVal sender As Object, ByVal e As EventArgs)
                RemovePlaceHolder()
                AddHandler Me.GotFocus, AddressOf txt_focus
                RemoveHandler Me.Click, AddressOf txt_click
            End Sub
    
            Private Sub RemovePlaceHolder()
                Me.Text = ""
                Me.ForeColor = TextForeColor
                Me.Font = TextFont
            End Sub
    
            Private Sub txt_lostfocus(ByVal sender As Object, ByVal e As EventArgs)
                If String.IsNullOrEmpty(Me.Text) Then
                    SetPlaceHolder(False)
                End If
            End Sub
    
            Private Sub txt_focus(ByVal sender As Object, ByVal e As EventArgs)
                If Me.Text = PlaceholderText Then
                    RemovePlaceHolder()
                End If
            End Sub
        End Class
    
    End Namespace
    
    0 讨论(0)
  • 2020-11-22 01:10

    Using WinForms on .NET Core:

    This has been greatly simplified in .NET Core. You can directly add placeholder text by modifying the new PlaceholderText Property of the TextBox.

    public virtual string PlaceholderText { get; set; }
    

    Note that you would probably still have to edit the ForeColor if you want to get a colored Placeholder Text. The PlaceholderText field is visible when the Text field is null or empty.

    0 讨论(0)
  • 2020-11-22 01:13
    Private Sub randomSubName() Handles txtWatermark.Click
       txtWatermark.text = ""
    End Sub
    

    Make the default text of the textbox whatever you want the watermark to be, I assume in this example you name the textbox txtWatermark

    Hey, I'm new. So sorry if I terribly screwed up the post... I also have no idea if this works...

    0 讨论(0)
提交回复
热议问题