4

示例代码:

    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”的文字。我的问题是“为什么?” 和“有什么方法可以控制特定 ID,而无需一次手动地对 div.Controls[] 进行递归搜索一个元素?”

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

4

3 回答 3

4

据我所知,如果不将控件添加到页面,就无法完成我想要完成的工作。如果我不得不猜测,我会说 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;
    }
于 2010-08-25T13:11:04.640 回答
2

将您的代码更改为

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

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

于 2010-08-24T19:36:56.213 回答
0

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

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

于 2010-08-24T18:40:56.247 回答