6

I am currently looping through all the controls on my page and setting certain types (TextBox, CheckBox, DropDownList, etc.) to Enabled=False under certain conditions. However I notice an obvious page load increase looping like this. Is it possible to only get certain types of controls from the Page.Controls object rather than Loop through them all? Possibly with something like LINQ?

James P. Wright
  • 8,991
  • 23
  • 79
  • 142
  • 2
    Can you post sample code? I don't think iterating `Page.Controls` should be that big of a performance hit on its own. – jevakallio Feb 25 '11 at 21:52

3 Answers3

14

This cannot be done entirely using LINQ but you could have an extension defined like this

static class ControlExtension
    {
        public static IEnumerable<Control> GetAllControls(this Control parent)
        {
            foreach (Control control in parent.Controls)
            {
                yield return control;
                foreach (Control descendant in control.GetAllControls())
                {
                    yield return descendant;
                }
            }
        }
    }

and call

this.GetAllControls().OfType<TextBox>().ToList().ForEach(t => t.Enabled = false);
Bala R
  • 107,317
  • 23
  • 199
  • 210
5

You could loop through all the control (an nested ones):

private void SetEnableControls(Control page, bool enable)
{
    foreach (Control ctrl in page.Controls)
    {
        // not sure exactly which controls you want to affect so just doing TextBox
        // in this example.  You could just try testing for 'WebControl' which has
        // the Enabled property.
        if (ctrl is TextBox)
        {
            ((TextBox)(ctrl)).Enabled = enable; 
        }

        // You could do this in an else but incase you want to affect controls
        // like Panels, you could check every control for nested controls
        if (ctrl.Controls.Count > 0)
        {
            // Use recursion to find all nested controls
            SetEnableControls(ctrl, enable);
        }
    }
}

Then just call it initally with the following to disable:

SetEnableControls(this.Page, false);  
Kelsey
  • 47,246
  • 16
  • 124
  • 162
  • The OP is asking if there is any way to do this without looping. – kevev22 Feb 25 '11 at 22:04
  • @kevev22: how do you want to get certain control types of the page even from nested controls without any loop? There is no page-function `getControls(Type type)` that returns alls controls from a given type and linq would loop as well. – Tim Schmelter Feb 25 '11 at 22:09
  • @kevev22 I dont think there is a way without doing some sort of looping and recursion... Can you tell me how to get to the moon without a rocket ship :) – Kelsey Feb 25 '11 at 22:11
  • I am not saying there is a way to do it without looping. The question was 'Is there a way to do it without looping?'. I think a complete answer would start with 'No there is no way to do it without looping, but since you have to loop here is a nice way'. – kevev22 Feb 25 '11 at 22:21
  • @kevev22: i agree. @Kelsey: this answer would be better if it would enable to pass the type as parameter of the controls that should be enabled/disabled. This approach is somewhat static for this question. – Tim Schmelter Feb 25 '11 at 22:33
  • @Tim Schmelter I am sure it could be a lot better and your free to edit it :) I just put something down quickly and was hoping the OP would suit it to whatever specific they require. – Kelsey Feb 25 '11 at 22:45
0

I like the solution in this link LINQ equivalent of foreach for IEnumerable<T>

Worked quite well for me!

You can do the iteration of controls using a linq query like

    (from ctrls in ModifyMode.Controls.OfType<BaseUserControl>()

                 select ctrls).ForEach(ctrl => ctrl.Reset());

Here BaseUserControl is a base class which all my controls use, you could very well use Control itself here, and the extension method allows you to club iteration and execution.

Community
  • 1
  • 1
Azerax
  • 41
  • 1
  • 8