Istrebitel
Istrebitel

Reputation: 3083

need to change TextBox.Text inside TextChanged, something forces form close

I am making a TextBox behave like if it could store a null value. In order to do that, i have a variable NullMode that indicates wether the value is stored is Null, and in TextChanged i set that to false, and on specific user action i set it to true and Text to a value that indicates that there is null inside the textbox. Then, based on NullMode, textbox is drawn differently.

Now, i have a semaphore-like approach in order to prevent event handle from firing when i dont need it. Here is how it looks:

                private void input_TextChanged(object sender, EventArgs e)
        {
            if (_preventTextBoxEvents) 
                return;

            _preventTextBoxEvents = true;

            //if (NullMode)
            //  Text = "";
            NullMode = false;
            ValidateInput();

            _preventTextBoxEvents = false;
        }

Now, if i need to set a textbox text to something that should show while in nullmode, i just set _preventTextBoxEvents before i do to true and it works all right.

BUT! I need to also remove the text when user tries to input something into the textbox! So i need to set Text to "". Problem is, if i uncomment that, form is closed after the event handler exits. I cannot prevent it (e.Cancel = true in FormClosing doesnt help!) and do not understand what can be causing it. There is no error message too (and i'm not doing try-catch).

My logic, when i do Text="". OnTextChanged should fire, it should call my TextChanged and it will see _preventTextBoxEvents is true and exit, so there would be no stack overflow / infinite recursion.

What is going on?

Upvotes: 3

Views: 4295

Answers (1)

Steve
Steve

Reputation: 216293

It should be so (assuming your text box is called input)

if (NullMode) 
    input.Text = ""; 

Text alone refers to the current form caption, not to the input.Text property.
However let me say that your approach is dangerous. If, for some reason, your ValidateInput throws an exception, you will exit from the event handler without restoring the global _preventTextBoxEvents to false;

Add a try - catch - finally

    private void input_TextChanged(object sender, EventArgs e)   
    {   
        if (_preventTextBoxEvents)    
            return;   

        _preventTextBoxEvents = true;   
        try
        {
           if (NullMode) input.Text = "";   
           NullMode = false;   
           ValidateInput();   
        }
        catch(Exception ex)
        {
            // Inform user of the exception occurred inside your ValidateInput
            MessageBox.Show(ex.Message);
        }
        finally
        {
            // Be sure to restore this global to a functioning value.
            _preventTextBoxEvents = false;   
        }
    }   

Moreover you could remove the logic for _preventTextBoxEvents simply disconnecting your TextChanged event when your program enters in the event code:

try
{
    input.TextChanged -= new EventArgs(input_TextChanged);
    // Now, the input textbox is no more connected to this code, you 
    // could happily change the textbox text without worry to reenter in this code
}
...
finally
{
    // Work finished, reconnect this code to the event TextChanged
    input.TextChanged += new EventArgs(input_TextChanged);
}

Upvotes: 3

Related Questions