When MaskedTextBox.SelectAll doesn't Select All...
A client recently asked for a seemingly easy feature to be added to an application of his. The application consists of a form with a number of MaskedTextBox objects, and those textboxes are supposed to select their contents once focused, so any keypress after giving focus would overwrite the existing text in the textbox.
Shouldn't be hard, right? Just subscribe to the textbox.Enter event and then call textbox.SelectAll(), that's what, five minutes? An hour later, things still weren't working as they should. For some reason, the SelectAll() call didn't work. It just didn't select anything (although at one point I was able to make it select only a part of the contents, but that was, well, quite useless for my client).
Turns out MaskedTextBox is an eager little sport. If a mask is set, the control does some selecting of its own when it gets focused, and thus it overrides anything you try to do yourself in response to these events. Cute, but annoying. Once I realised that, the solution wasn't too far away: I had to postpone the SelectAll() call so it executes after the focus events have been handled by MaskedTextBox.
Thankfully, Windows Forms provides a BeginInvoke method that will do just that: Control.BeginInvoke will post a Win32 message (you know, WM_*) to the message queue. This message won't be picked up until the focus events have been processed, so we can leverage this to postpone our SelectAll() call.
Doing this is pretty easy using MethodInvoker and anonymous delegates in .NET 2.0:
textbox.BeginInvoke(new MethodInvoker(textbox.SelectAll));
If only they would have mentioned this in the documentation. You know, the thing you read to find out about stuff like that :)
Posted by Filip at 11:30.