【问题标题】:Can't enumerate controls in CodeBehind无法枚举 CodeBehind 中的控件
【发布时间】:2013-03-30 11:33:56
【问题描述】:

我在*.aspx 页面中定义了html 表,而不是带有asp-tags 之一。然后我在该表的行中添加了一些 asp 控件:<asp:CheckBox>

我已经定义了很多复选框,因为我需要为用户提供大量的选择并且我不能最小化复选框的数量。

CodeBehind 中,我想枚举整个控件以查找GetType().Name 所需的内容,然后将其添加到临时列表中以供将来操作。

但是我遇到了麻烦,在调试器中我看不到任何复选框,并且控件的数量非常少。

我正在像这样枚举页面中的控件:

foreach (var item in Page.Controls)
{
    if (item.GetType().Name == "CheckBox")
    {
         CheckBox checkBox = item as CheckBox;

         if (checkBox.ID != null && checkBox.ID != String.Empty && checkBox.Checked)
         {
             arrayDocs.Add(checkBox.ID);
         }
    }
}

我的页面的完整代码:

aspx:http://pastebin.com/gUs2LchL

后面的代码:http://pastebin.com/5tfnKJSt

【问题讨论】:

  • 如果你想枚举页面上的所有控件,你需要递归地进行。
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • @Magnus 递归? 23个checkbox,递归确实有重复的步骤,试想想怎么会慢?即使您使用尾递归,我想,asp 页面上的任何控件都在某个控件容器中,您可以使用 foreach() 块对其进行枚举。这个主题的主要问题是,我无法链接到包含所有复选框的容器来枚举它们,也无法从主Page.Controlsthis.Controls 加载,这很奇怪。我想复选框在表服务器端控件中,但我试图获取元素 - 没有成功,结果相同
  • @OlegOrlov 至少您会发现复选框位于哪个容器中。除非页面中有数百万个控件,否则递归迭代控件应该非常快。试试看吧。
  • @Magnus 查看其工作的简单递归方案:upload.wikimedia.org/wikibooks/ru/b/b4/Treerecurs.jpg 然后想象一下重复计算将如何为简单迭代分配内存?例如,要迭代地获得一些控件,您应该为每个控件分配 64 Kb(仅用于示例)如果您有 6 个控件,那么您应该加载每个控件,在简单的迭代中,您为每个新控件重新分配 PC 中相同的内存部分(内存range ) 使用您为堆栈新部分上的每个新控件分配的递归,大小为 64 kb。

标签: c# asp.net user-interface controls enumeration


【解决方案1】:

根据MSDN,Control.Controls 属性返回该控件的 控件的集合,而不是后代。只有直接包含在该控件中的服务器端控件才会成为集合的一部分。

如果您想在页面上构建所有控件的集合,您将需要递归地循环遍历控件以添加它们的子控件等等 - 正如 Magnus 正确说明的那样。

最有效/最有效的方法是从复选框的父容器构建集合,在本例中是 HtmlTable "tableDocs" 的单元格。

改变-

foreach (var item in Page.Controls)

到-

foreach (var item in tableDocs.Controls)

然后,您需要在到达复选框之前将子控件递归循环到至少两个级别(行 -> 单元格 -> 复选框)。

更直接的方法是使用泛型并创建一个类型化的 CheckBox 列表,其中包含您希望测试的所有复选框。

类似的东西-

var checkboxes = new List<CheckBox>{checkboxAuctionHistory, checkboxBackSaldo, checkboxBalanceDecrypted}; //And so on

    foreach (var checkbox in checkboxes)
    {
        if (!string.IsNullOrWhiteSpace(checkbox.ID) && checkbox.Checked)
            {
                arrayDocs.Add(checkbox.ID);
            }
        }
    } 

这有一个明显的缺陷,即每次向表单添加新复选框时都需要记住更改列表。

或者将复选框移出表或从中删除 runat="server" 属性,从 ASP.NET 控件树中删除表,并使复选框的容器为“form1”。

页面上的大多数其他标记都没有 runat="server",因此这些元素不是 ASP.NET 控件树的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    相关资源
    最近更新 更多