如何实现显示“在此处输入”的TextBox?

时间:2010-03-21 12:50:44

标签: c# winforms textbox

显示“此处键入... ”,直到用户将文本输入TextBox,这是众所周知的可用性功能。如何在C#中实现此功能?

我的想法是覆盖OnTextChanged,但处理“在此输入”的文本更改的逻辑有点棘手......

在初始化时显示“在此输入”并在第一次输入时将其删除很容易,但我想在每次输入的文本变空时显示消息。

15 个答案:

答案 0 :(得分:36)

对我有用的东西:

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;
    }
  };

其中bool waterMarkActive是类成员变量,textBoxTextBox。这可能应该被封装了:)这种方法可能存在一些问题,但我目前还没有意识到这一点。

我最近发现Windows支持文本框中的水印;它们被称为提示横幅(见here)。它很容易实现:

// 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.");

其中textBoxTextBox的实例,0x1501是Windows消息EM_SETCUEBANNER的代码,wParam可能是TRUE }(非零)或FALSE(零),lParam是您要显示的水印。 wParam表示何时应显示提示横幅;如果设置为TRUE,则即使控件具有焦点,也会显示提示横幅。

答案 1 :(得分:24)

您要找的是带有“水印

的文本框

C#here有一个示例实现。

希望有所帮助

答案 2 :(得分:8)

基于@Pooven的回答(谢谢!),我创建了这个类。适合我。

/// <summary>
/// A textbox that supports a watermak hint.
/// </summary>
public class WatermarkTextBox : TextBox
{
    /// <summary>
    /// The text that will be presented as the watermak hint
    /// </summary>
    private string _watermarkText = "Type here";
    /// <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 = true;
    /// <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 = true;
        this.Text = _watermarkText;
        this.ForeColor = Color.Gray;

        GotFocus += (source, e) =>
        {
            RemoveWatermak();
        };

        LostFocus += (source, e) =>
        {
            ApplyWatermark();
        };

    }

    /// <summary>
    /// Remove watermark from the textbox
    /// </summary>
    public void RemoveWatermak()
    {
        if (this._watermarkActive)
        {
            this._watermarkActive = false;
            this.Text = "";
            this.ForeColor = Color.Black;
        }
    }

    /// <summary>
    /// Applywatermak immediately
    /// </summary>
    public void ApplyWatermark()
    {
        if (!this._watermarkActive && string.IsNullOrEmpty(this.Text)
            || ForeColor == Color.Gray ) 
        {
            this._watermarkActive = true;
            this.Text = _watermarkText;
            this.ForeColor = Color.Gray;
        }
    }

    /// <summary>
    /// Apply watermak to the textbox. 
    /// </summary>
    /// <param name="newText">Text to apply</param>
    public void ApplyWatermark(string newText)
    {
        WatermarkText = newText;
        ApplyWatermark();
    }

}

答案 3 :(得分:4)

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)]string lParam);
  const int EM_SETCUEBANNER = 0x1501; 

  public Form1()
  {
      InitializeComponent();
      SendMessage(textBox1.Handle, EM_SETCUEBANNER, 1, "Username");
      SendMessage(textBox2.Handle, EM_SETCUEBANNER, 1, "Password");
  }

答案 4 :(得分:3)

我刚开始学习C#本学期所以我不是专家,但这对我有用: (这是使用Windows窗体)

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 :(得分:1)

处理丢失的焦点事件,如果属性Text为空,请使用默认字符串填充它。

答案 6 :(得分:1)

如果这是ASP.NET(而不是winforms),你可以这样做:

如果您使用的是jQuery,请将其添加到您的文档中(或者初始化您的页面):

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', '');
   });
}

如果要选择多个文本框,则需要进行一些小的重构(将if语句放在元素中的每个文本框中)。

答案 7 :(得分:1)

在C#的最后一个版本中,TextBox具有PlaceholderText属性,它可以完成所有工作。所以你只需要设置&#34;在这里输入...&#34;作为这个属性的价值。

答案 8 :(得分:0)

您可以在文本框背景中绘制字符串“在此处输入”,直到它为空

答案 9 :(得分:0)

如果这是针对ASP.NET的,那么您可以尝试TextBoxWatermark

如果这是针对Windows窗体的,则已在SO中回复here

答案 10 :(得分:0)

为什么要使用OnTextChanged? 当TextBox获得焦点时,我建议删除文本“在这里输入”。 当控件失去焦点且未输入任何文本时,您可以再次显示文本。

结果相同,不需要棘手的逻辑。

答案 11 :(得分:0)

生成与HTML WATERMARK类似的输出

这是我的文本框“水印”或“预览”文本的代码 - 效果很好!使用Windows窗体应用程序。

注意:此示例有3个文本框,每个文本框分别具有“鼠标离开”事件的方法和“鼠标输入”事件。

private void textBoxFav_Leave(object sender, EventArgs e) {
  TextBox textbox = (TextBox)sender;
  if (String.IsNullOrWhiteSpace(textbox.Text)) {
    textbox.ForeColor = Color.Gray;
    if (textbox.Name == "textBoxFavFood") {
      textbox.Text = "Favorite Food";
    }
    else if (textbox.Name == "textBoxFavDrink") {
      textbox.Text = "Favorite Drink";
    }
    else if (textbox.Name == "textBoxFavDesert") {
      textbox.Text = "Favorite Desert";
    }
  }
  else {
    textbox.ForeColor = Color.Black;
  }
}

private void textBoxFav_Enter(object sender, EventArgs e) {
  TextBox textbox = (TextBox)sender;
  if (textbox.Text == "Favorite Food" || textbox.Text == "Favorite Drink" || textbox.Text == "Favorite Desert") {
    textbox.Text = "";
    textbox.ForeColor = Color.Black;
  }
}

答案 12 :(得分:0)

如果你想避免控制调整大小问题和数据绑定问题并使代码更简单(好吧,这是有问题的),你可以使用标签并切换它的可见性。然后

    private void FilterComboBox_GotFocus(object sender, EventArgs e)
    {
        FilterWatermarkLabel.Visible = false;
    }

    private void FilterComboBox_LostFocus(object sender, EventArgs e)
    {
        if (!FilterWatermarkLabel.Visible && string.IsNullOrEmpty(FilterComboBox.Text))
        {
            FilterWatermarkLabel.Visible = true;
        }
    }

图像的另一种方法也避免了数据绑定问题 https://msdn.microsoft.com/en-us/library/bb613590(v=vs.100).aspx

答案 13 :(得分:0)

基于@ Joel的回答。我修了他的课(感谢基地!)

/// <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;
    }
}

答案 14 :(得分:0)

根据Ahmed Soliman Flasha的回答,使用以下课程:

public class TextBoxHint : TextBox
{
    string _hint;

    [Localizable(true)]
    public string Hint
    {
        get { return _hint; }
        set { _hint = value; OnHintChanged(); }
    }

    protected virtual void OnHintChanged()
    {
        SendMessage(this.Handle, EM_SETCUEBANNER, 1, _hint);
    }     

    const int EM_SETCUEBANNER = 0x1501;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)]string lParam);
}