views:

722

answers:

3

How does one lock the focus of a .net application to a specific control? For example, if I have a form with 5 text boxes, and I want them filled out in a specific order, how can I stop someone who is in box 1 from tabbing/clicking to box 2, or hitting OK or Cancel or anything else? Is there an easy way, or do I have to manually disable/enable each other control at the appropriate time?

The trouble with the obvious solution (Reset Focus when Focus is Lost) is that MSDN says you can lock up your machine that way:

(Source:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.leave.aspx)

Caution:

Do not attempt to set focus from within the Enter, GotFocus, Leave, LostFocus, Validating, or Validated event handlers. Doing so can cause your application or the operating system to stop responding. For more information, see the WM_KILLFOCUS topic in the "Keyboard Input Reference" section, and the "Message Deadlocks" section of the "About Messages and Message Queues" topic in the MSDN library at http://msdn.microsoft.com/library.

+3  A: 

Handle the Leave event of your textBox1. Inside the event handler, if your conditions are not met, for e.g. if the user has not entered some input, reset the focus back to the control.

private void textBox1_Leave(object sender, EventArgs e)
{
    if string.isNullOrEmpty(textBox1.Text)
    {
        textBox1.focus();
    }
}

Do this for each of your controls or do it more generic like:

private void textBox_Leave(object sender, EventArgs e)
{
    TextBox textBox = sender as TextBox;
    if (string.isNullOrEmpty(textBox.Text)
    {
        textBox.focus();
    }
}
Serhat Özgel
+2  A: 

basically, you must be draconian in your design.

  • Check when the textbox loses focus, and if it doesn't have a valid data entry, regain focus.
  • capture when the form tries to close --check if the textbox has the proper data, and if it doesn't cancel the close.
  • capture mouse events and check for the data, sending focus to where you want regardless of what the user is trying.

All that said though, this is a BAD idea and will lead to mad users. My suggestion is to come up with another paradigm for your data entry which can handle receiving the data in a robust form rather than being evil in your design and forcing certain behaviors.

Stephen Wrighton
+1  A: 

I think TextBox.Validating event is more appropriate, and it's meant for this specifically. Also it's much easier as you don't have to set the focus, all you need to do is set e.Cancel = true; to return focus to the current control

    void textBox1_Validating(object sender, CancelEventArgs e)
 {
  if (true) //Condition not met
  {
   e.Cancel = true;//Return focus to the current control
  }
 }

Make sure the CauseValidation under the property of the textbox is true, which is by default set to true anyway.

faulty