Giovanni S
Giovanni S

Reputation: 2110

Changing the properties of a dynamically created control

I have a Form with a LayoutPanel that has dynamically added buttons inside. The buttons are added at runtime, which works, but my problem is I'd like to set the properties to one of the buttons to disabled if a textBox is empty and enable it when it the textBox is not empty.

Here is a code example, with the error I am receiving below:

private void Form1_Load(object sender, EventArgs e)
{

    // Create 3 buttons

    Button button1 = new Button();
    button1.Name = "button1";
    tableLayoutPanel1.Controls.Add(button1, 0, 0);

    Button button2 = new Button();
    button1.Name = "button2";
    tableLayoutPanel1.Controls.Add(button2, 0, 0);

    Button button3 = new Button();
    button3.Name = "button1";
    tableLayoutPanel1.Controls.Add(button3, 0, 0);
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(textBox1.Text))
    {
        button1.Enabled = false;
    }
    else
    {
        button1.Enabled = true;
    }
}

CS0103 The name 'button1' does not exist in the current context

Should I be declaring the buttons elsewhere so the entire code can see that they do in fact exist or is my problem elsewhere? Thanks.

Upvotes: 1

Views: 1453

Answers (3)

Mark Hall
Mark Hall

Reputation: 54562

There are a couple ways you can do this, one would be to use the Find method of the TableLayoutPanel's Controls Collection like this.

private void textBox1_TextChanged(object sender, EventArgs e)
{
    Button btn =(Button)tableLayoutPanel1.Controls.Find("button1", true)[0];

    if (string.IsNullOrEmpty(textBox1.Text))
    {
        btn.Enabled = false;
    }
    else
    {
        btn.Enabled = true;
    }
}

The second would be to use the buttons Tag Property to determine which control to use, I have used this in the past for dynamically generated controls.

private void Form1_Load(object sender, EventArgs e)
{
    // Create 3 buttons
    Button button1 = new Button();
    button1.Name = "button1";
    button1.Tag = 1; //note the Tag property being used
    tableLayoutPanel1.Controls.Add(button1, 0, 0);

    Button button2 = new Button();
    button1.Name = "button2";
    button2.Tag = 2;
    tableLayoutPanel1.Controls.Add(button2, 0, 0);

    Button button3 = new Button();
    button3.Name = "button3";
    button3.Tag = 3;
    tableLayoutPanel1.Controls.Add(button3, 0, 0);

}


private void textBox1_TextChanged(object sender, EventArgs e)
{
    foreach (Control c in tableLayoutPanel1.Controls) //iterate through controls
    {
        if ((int)c.Tag == 1) //if Tag is equal then process
        {
            if (c is Button)
            {
                if (string.IsNullOrEmpty(textBox1.Text))
                {
                    ((Button)c).Enabled = false;
                }
                else
                {
                    ((Button)c).Enabled = true;
                }
                break; //if you have multiple controls to process remove this
            }          //and assign the same tag to the controls you want processed
        }
    }
}

Upvotes: 1

Abdellah OUMGHAR
Abdellah OUMGHAR

Reputation: 3755

You must declare a Button outside Form1_Load if you want to access the button with name directly from other methods, because in your case the buttons are just available in the Form1_Load method :

Button button1;

private void Form1_Load(object sender, EventArgs e)
{
    // Create 3 buttons
    button1 = new Button();
    button1.Name = "button1";
    tableLayoutPanel1.Controls.Add(button1, 0, 0);
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    button1.Enabled = !string.IsNullOrEmpty(textBox1.Text);
}

or if you want declare Buttons inside Form1_Load, you can access to Button like this :

private void textBox1_TextChanged(object sender, EventArgs e)
{
    var btn = tableLayoutPanel1.Controls.OfType<Button>().Where(x => x.Name == "button1").FirstOrDefault();
    (btn as Button).Enabled = !string.IsNullOrEmpty(textBox1.Text);
}

Upvotes: 2

abrown
abrown

Reputation: 715

As an alternative, you could dynamically get the control from the Layout Panel and set the enabled property like this:

private void textBox1_TextChanged(object sender, EventArgs e)
{
        Control button = tableLayoutPanel1.Controls["button1"];

        button.Enabled = string.IsNullOrEmpty(textBox1.Text) ? false : true;
}

This approach is not as "safe" as declaring the buttons at form level, but I thought it would be useful to mention for times when you need to be genuinely dynamic in referencing controls.

Upvotes: 1

Related Questions