Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying a TextBox control on the Leave event prevents tabbing out of the control

I've got a standard TextBox control which I'm trying to have mimic the "soft descriptions" like those found in the title and tags boxes on StackOverflow. Essentially, when the user's focus enters the control, it hides the description ("Username") in this case, and sets alignment and color to be that of a standard text control. When the user leaves the textbox, I want to check if the user actually entered anything, and put the username display back up otherwise.

For example:

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

Unfortunately, when I setup these events, the user cannot tab out of the username control. The control simply flickers and control returns to the textbox control itself until the user has entered something, skipping over the event body.

If I call this.SelectNextControl() in the event, then the event enters an infinite loop.

Does anybody see what I'm doing wrong?

like image 497
Billy ONeal Avatar asked Feb 18 '10 19:02

Billy ONeal


2 Answers

Looks like another way around it (Using Reflector to see that it does refocus back on the Control if the focus was there to begin with). I think it is a bug, but looks like they were just reusing RecreateHandleCore function to redraw the text. So another way would be to focus off the textbox first, then continue:

  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;
     }
  }
like image 71
SwDevMan81 Avatar answered Sep 18 '22 18:09

SwDevMan81


Setting the TextAlign property on the TextBox control returns focus back to that control. That seems like a bug.

Here is a quick fix:

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

(although somewhat of a hack around unexpected behavior). Simply disable the control before changing the alignment. Another "fix" would be to keep things aligned left, or to measure how many spaces to insert to simulate centering the text.

like image 20
Bill Avatar answered Sep 20 '22 18:09

Bill