在Leave事件上修改TextBox控件可防止跳出控件

时间:2010-02-18 19:30:20

标签: c# .net winforms textbox

我有一个标准的TextBox控件,我试图模仿“软描述”,就像在StackOverflow上的标题和标签框中找到的那样。实质上,当用户的焦点进入控件时,它会在这种情况下隐藏描述(“用户名”),并将对齐和颜色设置为标准文本控件的对齐和颜色。当用户离开文本框时,我想检查用户是否确实输入了任何内容,并以其他方式重新显示用户名显示。

例如:

    private void tbUsername_Enter(object sender, EventArgs e)
    {
        if (tbUsername.TextAlign == HorizontalAlignment.Center)
        {
            tbUsername.TextAlign = HorizontalAlignment.Left;
            tbUsername.ForeColor = SystemColors.ControlText;
            tbUsername.Text = String.Empty;
        }
    }

    private void tbUsername_Leave(object sender, EventArgs e)
    {
        if (tbUsername.Text == String.Empty)
        {
            tbUsername.TextAlign = HorizontalAlignment.Center;
            tbUsername.ForeColor = SystemColors.InactiveCaption;
            tbUsername.Text = "Username";
        }
    }

不幸的是,当我设置这些事件时,用户无法跳出用户名控件。控件只是闪烁并控制返回到文本框控件本身,直到用户输入内容,跳过事件正文。

如果我在事件中调用this.SelectNextControl(),则事件进入无限循环。

有人看到我做错了吗?

3 个答案:

答案 0 :(得分:6)

看起来是另一种方式(使用Reflector看到它确实重新聚焦在Control上,如果焦点在那里开始)。我认为这是一个错误,但看起来他们只是重新使用RecreateHandleCore函数来重绘文本。另一种方法是首先关注文本框,然后继续:

  private void LeaveEvent(object sender, EventArgs e)
  {
     if (String.IsNullOrEmpty(tbUsername.Text))
     {
        tbUsername.Text = USER_NAME;
        tbUsername.ForeColor = SystemColors.InactiveCaption;
        this.Focus();
        tbUsername.TextAlign = HorizontalAlignment.Center;
     }
  }

答案 1 :(得分:3)

在TextBox控件上设置TextAlign属性会将焦点返回到该控件。这似乎是一个错误。

这是一个快速修复:

tbUsername.Enabled = false;
tbUsername.ForeColor = SystemColors.InactiveCaption;
tbUsername.Text = "Username";
tbUsername.TextAlign = HorizontalAlignment.Center;
tbUsername.Enabled = true;

(虽然有点出乎意料的行为)。只需在更改对齐之前禁用控件。另一个“修复”是将事物保持对齐,或者测量要插入多少空格以模拟文本居中。

答案 2 :(得分:3)

使用BeginInvoke

    private void tbUsername_Leave(object sender, EventArgs e)
    {
        BeginInvoke(new MethodInvoker(OnLeave));
    }

    private void OnLeave()
    {
        if (tbUsername.Text == String.Empty)
        {
            tbUsername.TextAlign = HorizontalAlignment.Center;
            tbUsername.ForeColor = SystemColors.InactiveCaption;
            tbUsername.Text = "Username";
        }
    }