迭代ControlCollection返回0结果

时间:2014-10-23 06:10:08

标签: c# asp.net generics webforms system.web.ui.webcontrols

我有以下方法在我的帮助程序类中返回WebControl的List:

public static List<T> GetControls<T>(ControlCollection cCol) where T : WebControl
{
    List<T> results = new List<T>();
    foreach (Control control in cCol)
    {
        if (control is T)
            results.Add((T)control);

        if (control.HasControls())
            GetControls<T>(control.Controls);
    }
    return results;
}

在我的aspx页面上,有一个UpdatePanel包含3个asp:CheckBoxList控件。要填充我的列表,我使用上述方法,其中CheckBoxPanel是包含我的控件的UpdatePanel。

List<CheckBoxList> cbCol = Helper.GetControls<CheckBoxList>(CheckBoxPanel.Controls);

此行返回0结果,表示我的方法GetControls<T>(ControlCollection cCol)错误。

请帮助我找到我的思路中的缺陷。

2 个答案:

答案 0 :(得分:1)

您的results是一个局部变量。因此,对于每个递归调用,您都会添加一些控件并将其忘记。

它应该在所有递归调用中作为参数传递,然后才会在同一列表中填充控件。

未经测试,但以下代码应该有效:

private static List<T> GetControls<T>(ControlCollection cCol, List<T> results) where T : WebControl
{
    foreach (Control control in cCol)
    {
        if (control is T)
            results.Add((T)control);
        if (control.HasControls())
            GetControls<T>(control.Controls, results);
    }

    return results;
}

public static List<T> GetControls<T>(ControlCollection cCol) where T : WebControl
{
    return GetControls(cCol, new List<T>());
}

答案 1 :(得分:0)

您可以使用Snram解决方案,或者只是简单地使用:

if (control.HasControls())
            results.AddRange(GetControls<T>(control.Controls));

您唯一需要的是将重新调用的输出添加到结果中。

Snram解决方案可能会更好,因为您不会在每次重复调用时创建列表实例(在我的解决方案中,GC必须处理未使用的列表并将其从内存中删除)。