ASP.Net / C#,如何循环遍历页面上的特定控件?

6

我目前正在遍历页面上的所有控件,并在某些条件下将特定类型(TextBox、CheckBox、DropDownList等)设置为Enabled=False。 然而,我注意到像这样循环会导致页面加载明显增加。是否可能仅从Page.Controls对象中获取某些类型的控件,而不是遍历它们?可能使用类似于LINQ的东西吗?


2
你能发布一些示例代码吗?我认为迭代 Page.Controls 本身不应该对性能造成太大的影响。 - jevakallio
3个回答

14

这不能完全使用LINQ来完成,但您可以定义一个扩展方法来实现,如下所示:

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;
                }
            }
        }
    }

并调用

this.GetAllControls().OfType<TextBox>().ToList().ForEach(t => t.Enabled = false);

美观简洁。 - James P. Wright

5
你可以循环遍历所有的控件(包括嵌套的控件):
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);
        }
    }
}

然后,只需使用以下内容进行初始调用以禁用:

SetEnableControls(this.Page, false);  

OP 询问是否有不使用循环的方法来实现这个。 - kevev22
@kevev22:你想如何获取页面上特定的控件类型,即使是从嵌套控件中获取,而不需要任何循环?没有页面函数getControls(Type type)可以返回给定类型的所有控件,而且linq也会进行循环。 - Tim Schmelter
@kevev22 我认为没有不需要进行某种形式的循环和递归的方式... 您能告诉我如何在没有火箭的情况下到达月球吗 :) - Kelsey
我并不是说有一种可以不使用循环就能完成的方法。问题是“有没有一种不使用循环就能完成的方法?”。我认为一个完整的答案应该以“不,没有一种不使用循环就能完成的方法,但既然你必须要使用循环,这里提供了一种好的方式”开始。 - kevev22
@kevev22:我同意。 @Kelsey:如果它能够将类型作为控件应启用/禁用的参数传递,那么这个答案会更好。对于这个问题,这种方式有点静态。 - Tim Schmelter
@Tim Schmelter,我相信它可以做得更好,你可以自由编辑 :) 我只是快速地放了一些东西,并希望原作者能将其适应到他们所需要的任何具体情况中。 - Kelsey

0

我喜欢这个链接中的解决方案 LINQ equivalent of foreach for IEnumerable<T>

对我来说效果很不错!

你可以使用类似于linq查询的方式来迭代控件

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

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

这里的BaseUserControl是我所有控件使用的基类,你也可以在这里直接使用Control本身,而扩展方法允许你将迭代和执行组合在一起。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接