Search code examples
c#winformseventstextchanged

textchanged event calling custom method but custom method reports textbox text is empty


I've not touched C# in some time, was trying to help a new programmer friend of mine and became utterly stumped by the following:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        activateEnterButton();
        TextBox t = (TextBox)sender;
        string theText = t.Text;
        MessageBox.Show("text: " +theText);
    }

    private void activateEnterButton()
    {
       bool allGood = true;

        foreach (Control control in Controls )
        {
            if (control is TextBox)
            {
                string test = ((TextBox)control).Text;

                if (test.Length == 0)
                {
                    MessageBox.Show("text: " +test);
                    allGood = false;
                    break;
                }
            }
        }
        btnEnter.Enabled = allGood; 
    }

Our goals is utterly simple: We have 5 textboxes and each needs to have some text in them before a button is enabled. When each has text, button is enabled.

When I walk through the code while debugging everything is called okay but no matter how much text I put in the textbox the activateEnterButton never knows it's there. The two MessageBoxes show different output as well: the one in the activateEnterButton never has any, the one in the event handler always does.

Any assistance would be greatly appreciated. Thank you.

I have removed the calls to the activateEnterButton(), I have put guts of that code inside the event handler for textBox5 but the button is still not being enabled.

The answer I accepted didn't give me the functionality I wanted (entering data into textbox5 would make the button active)the following code gave me all the functionality I wanted. And lastly, the reason for my errors were because A) foreach iterates from the last control to the first, and B) the last textbox control I have on the form is a ReadOnly textbox control, its text is always "", hence I was always getting dumped out of my earlier code. At any rate, new code:

    private void checkMe()
    {
        bool allGood = true;

        foreach (Control control in Controls)
        {
            // Make sure the ReadOnly textbox doesn't cause false
            if (control.Name.Equals("ReadOnlyTextBox"))
            {
               // MessageBox.Show("hidden textbox: " + ((TextBox)control).Text);
                allGood = true;

            }
            else if (control is TextBox)
            {
                string test = ((TextBox)control).Text;

                //MessageBox.Show("test: " + test);

                if (test.Length < 1)
                {

                    allGood = false;
                   // MessageBox.Show("All textboxes need input");
                    break;
                }
                else
                {
                    allGood = true;
                }
            }
        }
        btnEnter.Enabled = allGood; 
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        checkMe();
    }

    private void textBox2_TextChanged(object sender, EventArgs e)
    {
        checkMe();
    }

    private void textBox3_TextChanged(object sender, EventArgs e)
    {
        checkMe();
    }

    private void textBox4_TextChanged(object sender, EventArgs e)
    {
        checkMe();
    }

    private void textBox5_TextChanged(object sender, EventArgs e)
    {
        checkMe();
    }

Solution

  • In your activateEnterButton() method you looping through the controls and if control is textbox; checking whether it has text or not.

    Say if textbox1 has fired the textchanged event; how does that guarantee that other textbox has text in it?

    You said in your post The two MessageBoxes show different output as well: .. that should be.

    say textbox1 have fired textchanged event and so does in textchanged event you have the text displayed in messagebox but in method activateEnterButton() where you are looping through all controls in form there is no guarantee of order like textbox1 .. 5 (in that order loop will check them) and you are breaking out pf loop once it has no text. So does, in your method you don't see any text in messagebox.

    Best way of doing it would be as below (consider that you have TextBox 1..5; have the textchanged on TextBox5 only.)

    private void textBox5_TextChanged(object sender, EventArgs e)
    {
       bool allGood = false;
    
        foreach (Control control in Controls )
        {
            if (control is TextBox)
            {
                string test = ((TextBox)control).Text;
    
                if (test.Length > 0)
                {
                    allGood = true;
                }
                else
                {
                    MessageBox.Show("Fill all textbox first");
                    break;
                }
            }
        }
        btnEnter.Enabled = allGood; 
    }
    

    Hope this helps.