Winforms – Setting Focus() in Leave events
Although we live in 2012, there are still lots of code based on Winforms. And probably these codebases will exist in MANY years. But when I am set to do some UI stuff I struggle with the execution of events and what is allowed/disallowed.
Today I was working on a pretty simple task: When leaving a textbox, do some validation, and if the validation fails, set the focus to the textbox again. This is simple, but I had some stuff going on in the Enter event on the textbox and I didn’t want that to execute when the validation failed so I made this method
private void PreventKundenrLeave() { tKundenr.Enter -= KundenrOnEnter; tKundenr.Focus(); tKundenr.SelectAll(); _oldValue = null; tKundenr.Enter += KundenrOnEnter; }
This method ensures that the focus is still at the textbox if validation fails and and the Focus() method will be invoked AFTER the eventhandler on the Enter event has been removed.
But that didn’t work! The eventhandler still fired.
So I read in MSDN that you should absolutely under no circumstances do the following:
Do not attempt to set focus from within the Enter, GotFocus, Leave, LostFocus, Validating, or Validated event handlers.
The trick is to postpone the execution of the code until the Leave event is finished. This can be done with the BeginInvoke method.
private void tKundenr_Leave(object sender, EventArgs e) { this.BeginInvoke((MethodInvoker)delegate { PreventKundenrLeave(); }); }