Making a WinForms TextBox behave like your browser's address bar

Judah Gabriel Himango picture Judah Gabriel Himango · Sep 19, 2008 · Viewed 120.2k times · Source

When a C# WinForms textbox receives focus, I want it to behave like your browser's address bar.

To see what I mean, click in your web browser's address bar. You'll notice the following behavior:

  1. Clicking in the textbox should select all the text if the textbox wasn't previously focused.
  2. Mouse down and drag in the textbox should select only the text I've highlighted with the mouse.
  3. If the textbox is already focused, clicking does not select all text.
  4. Focusing the textbox programmatically or via keyboard tabbing should select all text.

I want to do exactly this in WinForms.

FASTEST GUN ALERT: please read the following before answering! Thanks guys. :-)

Calling .SelectAll() during the .Enter or .GotFocus events won't work because if the user clicked the textbox, the caret will be placed where he clicked, thus deselecting all text.

Calling .SelectAll() during the .Click event won't work because the user won't be able to select any text with the mouse; the .SelectAll() call will keep overwriting the user's text selection.

Calling BeginInvoke((Action)textbox.SelectAll) on focus/enter event enter doesn't work because it breaks rule #2 above, it will keep overriding the user's selection on focus.

Answer

Judah Gabriel Himango picture Judah Gabriel Himango · Sep 19, 2008

First of all, thanks for answers! 9 total answers. Thank you.

Bad news: all of the answers had some quirks or didn't work quite right (or at all). I've added a comment to each of your posts.

Good news: I've found a way to make it work. This solution is pretty straightforward and seems to work in all the scenarios (mousing down, selecting text, tabbing focus, etc.)

bool alreadyFocused;

...

textBox1.GotFocus += textBox1_GotFocus;
textBox1.MouseUp += textBox1_MouseUp;
textBox1.Leave += textBox1_Leave;

...

void textBox1_Leave(object sender, EventArgs e)
{
    alreadyFocused = false;
}


void textBox1_GotFocus(object sender, EventArgs e)
{
    // Select all text only if the mouse isn't down.
    // This makes tabbing to the textbox give focus.
    if (MouseButtons == MouseButtons.None)
    {
        this.textBox1.SelectAll();
        alreadyFocused = true;
    }
}

void textBox1_MouseUp(object sender, MouseEventArgs e)
{
    // Web browsers like Google Chrome select the text on mouse up.
    // They only do it if the textbox isn't already focused,
    // and if the user hasn't selected all text.
    if (!alreadyFocused && this.textBox1.SelectionLength == 0)
    {
        alreadyFocused = true;
        this.textBox1.SelectAll();
    }
}

As far as I can tell, this causes a textbox to behave exactly like a web browser's address bar.

Hopefully this helps the next guy who tries to solve this deceptively simple problem.

Thanks again, guys, for all your answers that helped lead me towards the correct path.