tags:

views:

69

answers:

4

I want to get a collection of all label controls that are part of a user control. I have the following code:

        var labelControls = from Control ctl in this.Controls
                            where ctl.GetType() == typeof(Label)
                            select ctl;

but the result is zero results.

Please assist. Thanks.

Edit I have also tried the following code without success.

        this.Controls
            .OfType<Label>()
            .Where(ctl => ctl.ID.Contains("myPrefix"))
            .ToList()
            .ForEach(lbl => lbl.ForeColor = System.Drawing.Color.Black);

Again, without success.

A: 

Does this.Controls really contain controls with type Label?

wRAR
This should be a comment on the question.
Jeff Yates
+1  A: 

Controls.OfType<Label>() - thats all

For nested controls

public static class ext
{
    public static List<Label> GetLabels(this Control control)
    {
        var chList = control.Controls.OfType<Label>().ToList();
        chList.AddRange(((IEnumerable<Control>)control.Controls)
              .SelectMany(c => c.GetLabels()));
        return chList;
    }
}
vittore
This doesn't take into account any nested controls. Therefore, it is unlikely to change the OPs result of finding nothing.
Jeff Yates
A: 
var labelControls = this.Controls.OfType<Label>();
Mel Gerats
This doesn't take into account any nested controls. Therefore, it is unlikely to change the OPs result of finding nothing.
Jeff Yates
+5  A: 

Are you sure that the control whose child controls you are parsing actually directly contains Label controls? I suspect that it is a child of the main control that is hosting the labels, in which case, you need to recursively search through the UI tree to find the labels.

Something like:

public static IEnumerable<Label> DescendantLabels(this Control control)
{
   return control.Controls.DescendantLabels();
}

public static IEnumerable<Label> DescendantLabels(this ControlCollection controls)
{
    var childControls = controls.OfType<Label>();

    foreach (Control control in controls)
    {
       childControls = childControls.Concat(control.DescendantLabels());
    }

    return childControls;
}
Jeff Yates
i feel that you have infinite loop here, you always call DescendantLabels on the same list of controls... don't you?
vittore
The signatures don't match.control.Controls is a ControlCollection, not an IEnumerable<Control>
John
this line `var descendantControls = controls.DescendantLabels();` will call `IEnumerable<Label> DescendantLabels(this IEnumerable<Control> controls)` right?
vittore
@John: Fixed this.
Jeff Yates
OK, so I haven't gotten the code to run as controlControls is a ControlCollection, not IEnumerable<Control> and so won't call the 2nd method. I tried changing, but got a stackoverflow error.However, your first suspicion was correct: my control was contained by another control. I had an Html server control <div id="myID" runat="server"> container around the entire thing. I'm not sure what my origional intent for creating it as a server control was and I didn't remember that it was even there, but I changed it to a straight html control and the code now runs.Thanks.
John
@vittore: Fixed infinite loop. Sorry for the ironic StackOverflow
Jeff Yates
Great! It works. I have to say, I really like how the code reads with extension methods, including the LINQ methods.
John
@Jeff: look at my editted code, I feel i figured out what you was thinking to do (without foreach)
vittore