How do I implement a TextBox that displays “Type h

2019-01-17 09:43发布

Displaying "Type here to ..." until the user enters text into a TextBox is a well-known usability feature nowadays. How would one implement this feature in C#?

My idea is to override OnTextChanged, but the logic to handle the changes of text from and to "Type here" is a bit tricky...

Displaying "Type here" on initialization and removing it on first input is easy, but I want to display the message every time the entered text becomes empty.

16条回答
混吃等死
2楼-- · 2019-01-17 10:28

If this is ASP.NET (as opposed to winforms), you could do this:

If you are using jQuery, add this to your document ready (or however you initialize your page):

var $textbox = $("textbox selector"); // assumes you select a single text box
if ($textbox.val() == "") {
   $textbox.val("Type here to...");
   $textbox.one('focus', function() {
     $(this).attr('value', '');
   });
}

You'll need to do some small refactoring if you are selecting more than one text box (put the if statement inside of an each on the element).

查看更多
别忘想泡老子
3楼-- · 2019-01-17 10:34

You can draw string "Type here" to the textbox background until it empty

查看更多
虎瘦雄心在
4楼-- · 2019-01-17 10:37

I'm just starting to learn C# this semester so I'm not an expert, but this worked for me: (This is using windows forms)

private void Form1_Load(object sender, EventArgs e)
{
    textBox1.SelectionStart = 0;  //This keeps the text
    textBox1.SelectionLength = 0; //from being highlighted
    textBox1.ForeColor = Color.Gray;
}

private void textBox_MouseMove(object sender, MouseEventArgs e)
{
    Cursor.Current = Cursors.IBeam; //Without this the mouse pointer shows busy
}

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    if (textBox1.Text.Equals("Type here...") == true)
    {
        textBox1.Text = "";
        textBox1.ForeColor = Color.Black;
    }
}

private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
    if (textBox1.Text.Equals(null) == true || textBox1.Text.Equals("") == true)
    {
        textBox1.Text = "Type here...";
        textBox1.ForeColor = Color.Gray;
    }
}
查看更多
别忘想泡老子
5楼-- · 2019-01-17 10:40

If this is for ASP.NET then you can try TextBoxWatermark.

If this is for Windows Forms, this is already answered here in SO.

查看更多
Deceive 欺骗
6楼-- · 2019-01-17 10:40

Based on @Joel's answer. I fix his class (thanks for the base!)

/// <summary>
/// A textbox that supports a watermak hint.
/// Based on: https://stackoverflow.com/a/15232752
/// </summary>
public class WatermarkTextBox : TextBox
{
    /// <summary>
    /// The text that will be presented as the watermak hint
    /// </summary>
    private string _watermarkText;

    /// <summary>
    /// Gets or Sets the text that will be presented as the watermak hint
    /// </summary>
    public string WatermarkText
    {
        get { return _watermarkText; }
        set { _watermarkText = value; }
    }

    /// <summary>
    /// Whether watermark effect is enabled or not
    /// </summary>
    private bool _watermarkActive;
    /// <summary>
    /// Gets or Sets whether watermark effect is enabled or not
    /// </summary>
    public bool WatermarkActive
    {
        get { return _watermarkActive; }
        set { _watermarkActive = value; }
    }

    /// <summary>
    /// Create a new TextBox that supports watermak hint
    /// </summary>
    public WatermarkTextBox()
    {
        this.WatermarkActive = _watermarkActive;
        this.Text = _watermarkText;
    }

    protected override void OnCreateControl()
    {
        base.OnCreateControl();
        if (this.WatermarkActive)
            CheckWatermark();
    }

    protected override void OnGotFocus(EventArgs e)
    {
        base.OnGotFocus(e);
        CheckWatermark();
    }

    protected override void OnLostFocus(EventArgs e)
    {
        base.OnLostFocus(e);
        CheckWatermark();
    }        

    public void CheckWatermark()
    {
        if ((this.WatermarkActive) && String.IsNullOrWhiteSpace(this.Text))
        {
            ForeColor = Color.Gray;
            this.Text = _watermarkText;
        }
        else if ((this.WatermarkActive) && (!String.IsNullOrWhiteSpace(this.Text)))
        {
            if (this.Text == _watermarkText)
                this.Text = "";
            ForeColor = Color.Black;
        }
        else
            ForeColor = Color.Black;
    }
}
查看更多
Summer. ? 凉城
7楼-- · 2019-01-17 10:41

Something that has worked for me:

this.waterMarkActive = true;
this.textBox.ForeColor = Color.Gray;
this.textBox.Text = "Type here";

this.textBox.GotFocus += (source, e) =>
  {
    if (this.waterMarkActive)
    {
      this.waterMarkActive = false;
      this.textBox.Text = "";
      this.textBox.ForeColor = Color.Black;
    }
  };

this.textBox.LostFocus += (source, e) =>
  {
    if (!this.waterMarkActive && string.IsNullOrEmpty(this.textBox.Text))
    {
      this.waterMarkActive = true;
      this.textBox.Text = "Type here";
      this.textBox.ForeColor = Color.Gray;
    }
  };

Where bool waterMarkActive is a class member variable and textBox is the TextBox. This probably should be encapsulated though :) There might be some issues with this approach, but I'm not currently aware of any.

I recently discovered that Windows support water marks in text boxes; they are called cue banners (see here). It's very easy to implement:

// Within your class or scoped in a more appropriate location:
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);

// In your constructor or somewhere more suitable:
SendMessage(textBox.Handle, 0x1501, 1, "Please type here.");

Where textBox is an instance of TextBox, 0x1501 is the code for the windows message EM_SETCUEBANNER, the wParam may either be TRUE (non-zero) or FALSE (zero), and lParam is the water mark you'd like to display. wParam indicates when the cue banner should be displayed; if set to TRUE then the cue banner will be displayed even when the control has focus.

查看更多
登录 后发表回答