0

In my form, I created two panels panel1 and panel2, within each panel I created one button named button1 and button2 respectively. if I want to add event handler using,

this.button1.Click += buttonEvent;

is fine. But, when I use foreach for each controls in form, It is not detected. Whats the problem here?

public myForm1() 
{
    InitializeComponent();
    foreach (Control c in this.Controls) 
    {
        TextBox tb = c as TextBox;
        if (tb != null)
        {  
            tb.TextChanged += textChanged;
        }
    }
}

How can I access the control in each of my panel using foreach?

Huntt
  • 185
  • 5
  • 14
Naveen Kumar V
  • 2,559
  • 2
  • 29
  • 43
  • 3
    You need to recursively look for subcontrols... I prefer to use a [Generic All controls method](http://stackoverflow.com/q/17454389/1324033) – Sayse Oct 21 '15 at 09:19
  • That looks complicated for me. I'm new to windows form. If I can access the 'this.control_name' in my constructor, then why can't in the 'this.Controls'? – Naveen Kumar V Oct 21 '15 at 09:25
  • 1
    Because the textboxes don't belong to the form, they belong to the panel. – Sayse Oct 21 '15 at 09:26
  • Then how is it possible to access via 'this.button1' instead of 'this.panel1.button1'? (I'm confused in this part) – Naveen Kumar V Oct 21 '15 at 09:28
  • 2
    @NaveenKumarV Your form is the main object. This contains a variable of button1 so you can access it. But the ControlsCollection only contains all controls which are directly placed on the form. If you use a panel this is an IContainerControl. This means it can hold other controls in it (like the form itself). So this panel has its own ControlCollection with all controls which are placed on the panel and so on and so on. Just because the button1 variable is avaible on form this dont mean it is added to ControlsCollection. – Sebi Oct 21 '15 at 09:46
  • @Sebi Your answer clarified my doubt :) – Naveen Kumar V Oct 21 '15 at 09:49

2 Answers2

1

You have to iterate over the controls in panel1 and panel2 instead of myForm1.

public myForm1() 
{
    InitializeComponent();
    foreach(Control c in panel1.Controls)
    {
        TextBox tb = c as TextBox;
        if(tb != null)
        {
            tb.TextChanged += textChanged;
        } 
    }
}

EDIT

To get the panels from the form:

for(int i = 0; i < 2; i++)
{
    Panel p = this.Controls["panel" + i];
    foreach(Control c in p.Controls)
    {
        TextBox tb = c as TextBox;
        if(tb != null)
        {
            tb.TextChanged += textChanged;
        }
    }
}
Huntt
  • 185
  • 5
  • 14
  • Seems I have to manually enter names for each panel within form? – Naveen Kumar V Oct 21 '15 at 09:30
  • No, you can get them dynamically I'll show you in the edit. – Huntt Oct 21 '15 at 09:31
  • My panel name may be different. I may even have 'n' number of panels, picturebox,etc. This is not dynamic. Although I appreciate your work bro. Eventhough I'm going to use your method :P, @sebi's answer is so generic. Thanks for your effort. – Naveen Kumar V Oct 21 '15 at 09:51
1

In your Form the Controls Collection only got the panels. Because a panel is a Container (as the Form) it has its own Controls Collection. So you have to iterate recursively for getting all subcontrols. So that if a new IContainerControl is detected like panel or usercontrol etc., you check them too.

In your case the panels Controls Collection will contain the button.

For example this method should search for an item:

The container should be your form.

private Control SearchControl(IContainerControl container, string name)
{
    foreach (Control control in this.Controls)
    {
        if (control.Name.Equals(name))
        {
            return control;
        }

        if (control is IContainerControl)
        {
            return SearchControl(control as IContainerControl, name);
        }
    }

    return null;
}
Huntt
  • 185
  • 5
  • 14
Sebi
  • 3,879
  • 2
  • 35
  • 62