【问题标题】:Trouble with FindControl and dynamicly created controlsFindControl 和动态创建的控件的问题
【发布时间】:2011-04-03 08:26:24
【问题描述】:

示例代码:

    var div = new HtmlGenericControl("div");
    div.Controls.Add(new Literal() { ID = "litSomeLit" });
    var lit = (Literal)div.FindControl("litSomeLit");
    Assert.IsNotNull(lit);

此代码未通过断言,因为 lit 为空。调试显示 div.Controls 肯定包含 ID 为“litSomeLit”的文字。我的问题是“为什么?”和“有没有什么方法可以在不递归搜索 div.Controls[] 的情况下一次通过一个元素来获得对特定 ID 的控制?”

我这样做的原因是我的实际应用程序并不是那么简单——我正在编写的一个方法被赋予了一个复杂的控件,其中包含多个可能配置的子控件。我需要访问一个特定的控件向下几层(例如,ID 为“txtSpecificControl”的控件可能位于StartingControl.Controls[0].Controls[2].Controls[1].Controls[3])。通常我可以只做FindControl("txtSpecificControl"),但是当控件只是动态创建时(如上面的示例代码),这似乎不起作用。

【问题讨论】:

    标签: c# asp.net web-controls dynamic findcontrol


    【解决方案1】:

    据我所知,如果不将控件添加到页面,就无法完成我想要完成的工作。如果我不得不猜测,我会说 FindControl 使用控件的 UniqueID 属性,它通常包含当前控件之上的所有控件的 ID(例如 OuterControlID$LowerControlId$TargetControlID)。只有当控件实际添加到页面时才会生成。

    无论如何,这是一个递归深度优先搜索 FindControl 的实现,当控件尚未附加到页面时,它将起作用:

        public static Control FindControl(Control parent, string id)
        {
            foreach (Control control in parent.Controls)
            {
                if (control.ID == id)
                {
                    return control;
                }
                var childResult = FindControl(control, id);
                if (childResult != null)
                {
                    return childResult;
                }
            }
            return null;
        }
    

    【讨论】:

      【解决方案2】:

      把你的代码改成

      var div = new HtmlGenericControl("div");
      Page.Controls.Add(div);
      div.Controls.Add(new Literal() { ID = "litSomeLit" });
      var lit = (Literal)div.FindControl("litSomeLit");
      

      据我所知 FindControl 仅在控件位于页面的可视树中时才有效。

      【讨论】:

      • 我无法进行更改,因为我的方法不知道控件应该添加到页面中的哪个位置。我可以将控件添加到页面,运行 FindControl,然后将其从页面中删除,但这似乎比手动进行递归搜索更难。
      • 我不明白你需要做一个 findControl。因为您正在创建文字,所以您无法保留变量,直到您将其添加到页面,然后使用 Page.FindControl 再次获取控件。
      【解决方案3】:

      当您确认控件在 Controls 集合中时,您是否通过直接检查该集合来做到这一点? FindControl() 在这种情况下可能不起作用。

      调试测试时,var lit 是否为空?如果是这样,您可能必须按项目索引访问成员,而不是使用 FindControl() 方法。

      【讨论】:

      • A) 是的,通过检查控件的 Controls 集合。但是,以下测试通过就好了:snipt.net/fishtoaster/findcontrol 这意味着 FindControl 应该能够找到它。 B) 错误,是的。这就是问题的全部意义——为什么它是空的,和/或我怎样才能绕过这个事实而不必通过项目索引来访问所有内容(这将是乏味的,因为我不知道到底有多深和我的目标控件在什么索引处)?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      • 2017-06-14
      • 1970-01-01
      相关资源
      最近更新 更多