Select all text in a textbox when the user clicks to focus

A tiny patch of code can sometimes save your users a lot of time. In a project I was working on, I used a lot of small textboxes to have the user input small numeric values. (Actually the textbox was a part of a kind of self-constructed NumericUpDown, but that’s another story.) Watching a tester work with the program, I saw him often clicking in the box and then starting typing his numbers, becoming increasingly annoyed that the numbers would be inserted at the position he clicked instead of overwriting the number that was already there.

Selecting all text in a box is nice behavior when you Tab into it, but in general I don’t like it for clicking in the box, because I expect the caret to be where I put it. There are exceptions to that: the browser address bar is one of them and that makes sense, because you more often than not want to overwrite the entire address instead of inserting or modifying parts. And, come to think about it, because these were just small numbers (up to 4 positions), I had to agree with the tester that it if you want to change a number, it would be a lot easier to just type over it, than it would be to start inserting or modifying digits.

So I wrote on override for the OnEnter event and executed a select all there. Done! That was easy. Or not… It didn’t work.

I tried attaching a handler to OnClick. Well, that didn’t work as expected either.

Agreeing with myself that I was not probably not the first trying to accomplish this, I did some googling and found a solution on (where else) StackOverflow, where Judah Himango asked the exact same thing.

The fast-gun alert in his question exactly matched my two failed attempts at a quick fix, so that looked promising. 🙂 With the help of the responders he eventually nailed it by hooking up just three small event handlers to the MouseUp, GotFocus and Leave events. I just added SelectAllOnFocus, a boolean property to be able to turn this behavior on and off.

this.tbxValue.Leave += new System.EventHandler(tbxValue_Leave);
this.tbxValue.GotFocus += new System.EventHandler(tbxValue_GotFocus);
this.tbxValue.MouseUp += new System.Windows.Forms.MouseEventHandler(tbxValue_MouseUp);

private bool selectAllOnFocus = true;
private bool selectAllDone = false;

void tbxValue_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
  if (SelectAllOnFocus && !selectAllDone && tbxValue.SelectionLength == 0)   {
    selectAllDone = true;
    tbxValue.SelectAll();
  }
}

void tbxValue_GotFocus(object sender, System.EventArgs e) {
  if (SelectAllOnFocus && MouseButtons == MouseButtons.None) {
    tbxValue.SelectAll();
    selectAllDone = true;
  }
}

void tbxValue_Leave(object sender, System.EventArgs e) {
  selectAllDone = false;
}

///
/// Set to true to select all contents of the textbox when the box receives focus by clicking it with the mouse
///
[DefaultValue(true)]
[Category("Behavior")]
[Description("Set to true to select all contents of the textbox when the box receives focus by clicking it with the mouse")]
public bool SelectAllOnFocus {
  get { return selectAllOnFocus; }
  set { selectAllOnFocus = value; }
}

Works great! In The Netherlands, there was a snail mail company that had a slogan about sending someone birthday cards: “kleine moeite, groot plezier” (Small effort, lots of fun). I hope that by adding this small piece of code I made a lot of my users happy.


Reacties

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *