Question

I have a TextBox for which I would like to run through a few conditions based on whether or not there is an integer entered in it. My operations take place from the code-behind of the window that the TextBox exists in.

Under the LostFocus event I would like to do the following:

  • Check if the string IsNullOrEmpty

    -If it is - set text to "Default Record"

  • Verify that the entered value is an Int

    If it isn't - Display a MessageBox(Ok Button), then set focus back on the TextBox

**This is what my LostFocus function looks like:

private void TextBox_LostFocus(object sender, RoutedEventArgs e) //Lost Focus
{
    if (string.IsNullOrEmpty(TextBox.Text))
        TextBox.Text = "Default Record";
    else if (Regex.IsMatch(TextBox.Text, @"^\d+$") == false)
    {
        MessageBox.Show("Illegal character in list.", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
        TextBox.Focus();
    }
}

The above function works well for testing whether or not the string IsNullOrEmpty, but I'm having problems with the else if condition. When I try to reset the focus back onto the TextBox I get an endless loop of MessageBoxes. Why is this and how do I fix it?

Update 1:

These are additional event handlers on the TextBox:

//State of View at startup
private void Document_Loaded(object sender, RoutedEventArgs e)
{
    //This is run because I need the TextBox to have focus at window startup
    TextBox.Focusable = true;
    TextBox.Focus();
}

xaml:

<UserControl Loaded="Document_Loaded" ... >
Was it helpful?

Solution

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...

From MSDN

OTHER TIPS

Keep track of whether the value has changed since you last showed the message box. Only show the messagebox if the value has changed since you last showed the message box.

I think like this:

private string lastValue = null;
private void TextBox_LostFocus(object sender, RoutedEventArgs e) //Lost Focus
{
    bool valueChanged = ( lastvalue != TextBox.Text );
    lastValue = TextBox.Text;
    if (string.IsNullOrEmpty(TextBox.Text))
        TextBox.Text = "Default Record";
    else if (Regex.IsMatch(TextBox.Text, @"^\d+$") == false && valueChanged )
    {
        MessageBox.Show("Illegal character in list.", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
        TextBox.Focus();
    }
}

When I try to reset the focus back onto the TextBox I get an endless loop of MessageBoxes

This happens because you're invoking the focus to the TextBox control, just when the event LostFocus is raised. When you close the MessageBox, the TextBox control got the focus, but the event LostFocus is continuously raised, and, because the else condition is satisfied, you will have an endless loop with the MessageBoxes.

I think you shouldn't use the event LostFocus to check the value of the TextBox and focus again. Have you considered the event TextChanged ?

You could then do something like this:

private void TextTest_TextChanged(object sender, TextChangedEventArgs e)
{
      Console.WriteLine("Text changed");

      /*  your logic here */   

      TextTest.Focus(); //it could be useless in this case!
}

You may also want to look at using a masked textbox to limit the input to integers. Then you want to do the validation (checking) when the user hits "ok/next/submit"... whatever will finish the entry.

http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask%28v=vs.90%29.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top