0

I'm trying to loop through the controls of a Windows Form by using something like:

public void FindTheControls(List<Control> foundSofar, Control parent) 
{
    foreach(var c in parent.Controls) 
    {
        if (c is IControl) //Or whatever that is you checking for 
        {
            foundSofar.Add(c);

            if(c.Controls.Count > 0) 
            {
                this.FindTheControls(foundSofar, c);
            }
        }
    }  
}

Then I want to store the names of the found controls in the Form in the List foundSofar:

private void button1_Click(object sender, EventArgs e)
{
    List<Control> foundSofar = new List<Control>();
    Form c = new Form();
    FindTheControls(foundSofar, c.Controls);
}

However c.Controls doesn't get recognised by the compiler, and so I can't get the controls included in Form.

PaulG
  • 13,871
  • 9
  • 56
  • 78
ArcaGraphy
  • 53
  • 3
  • 11
  • 2
    `Form c = new Form();` That's a blank form. – LarsTech May 13 '19 at 15:15
  • c.Controls in the line :FindTheControls(foundSofar, c.Controls); error message: Error CS1061 'Form' does not contain a definition for 'Contrlos' and no extension method 'Contrlos' accepting a first argument of type 'Form' could be found (are you missing a using directive or an assembly reference?) – ArcaGraphy May 13 '19 at 15:18
  • `Contrlos` is clearly a typo instead of `Controls`...and once which your code above does not reproduce, either. – ADyson May 13 '19 at 15:20
  • Your parameter is asking for a control in `Control parent`, but you are trying to pass a Control collection with `c.Controls`. Not the same thing. – LarsTech May 13 '19 at 15:22
  • 2
    So that's three mistakes, a typo for "Contrlos", a syntax error because the second argument needs to be "c", and a logical error since a new Form() has no controls. – Hans Passant May 13 '19 at 15:23
  • Once you correct the basic typo, you should run into the problem I've described, and fixed, in my answer below. – ADyson May 13 '19 at 15:28

2 Answers2

1

Seems that that answer can help you reach your goal:

All you need to do calling it without the were condition:

public IEnumerable<Control> GetAll(this Control control)
{
    var controls = control.Controls.Cast<Control>();

    return controls.SelectMany(ctrl => ctrl.GetAll())
                              .Concat(controls);
}

you can call it like:

List<Control> foundSofar = frm.GetAll().ToList();
Legion
  • 760
  • 6
  • 23
1
FindTheControls(foundSofar, c.Controls);

will not work, because the FindTheControls() method asks for a single Control object as the second paramter, but you are passing c.Controls in, which is a list. You should be getting an error message about this.

(N.B. Even if this worked, it would make no sense anyway, because if you passed in the direct children of the Form at the start of your method, it would not actually add those to the list of found controls, instead it would skip straight to the children of those controls.)

However, since Form inherits from Control, you can simply pass the Form itself as the starting point for the search:

FindTheControls(foundSofar, c);

N.B. It's also worth noting that Form c = new Form(); will create a new and empty form, so there are unlikely to be any controls to look at. Perhaps you intended to reference a specific type of form within your solution? Since we don't know what forms you have got in your solution, we can't give specific advice about what to do, all we can say is that what you've got now doesn't look like it would be very useful.

If, as per your comments below, you want to search the same form in which this code is located, then

FindTheControls(foundSofar, this);

will do that. this will represent the current instance of the current class, which is, of course, your form class.

ADyson
  • 57,178
  • 14
  • 51
  • 63
  • The for on which I am loking for controls is the "Form" itself. – ArcaGraphy May 13 '19 at 15:36
  • @Limko which form? The one in which this code is located? In that case just reference the current instance. i.e. `FindTheControls(foundSofar, this);` should do the job. (And note that your form will not be of type `Form`...it will _inherit_ from Form, so maybe its type is something like `MyForm` instead (you will have `public class MyForm` or similar in your form's code). So you _could_ create a new instance of `MyForm` and pass that to the function instead, but it's probably not necessary. – ADyson May 13 '19 at 15:37
  • yes, the one in which the code is licated. FindTheControls(foundSofar, this); seems to have solved my issue! Thanks a lot! – ArcaGraphy May 13 '19 at 15:46
  • one more question: if I have the same Situation, but I want to Access controls of another form in the current form, how would I write the function call? (i.e. instead of FindTheControls(foundSofar, this); ) – ArcaGraphy May 13 '19 at 16:20
  • See my earlier comment, above. Create an instance of the form class you want to search within. Or, if you already have a variable which holds a copy of the that form, then use that – ADyson May 13 '19 at 16:57