FindControl 和动态创建的控件出现问题

发布于 2024-09-16 00:06:44 字数 640 浏览 9 评论 0原文

示例代码:

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

此代码断言失败,因为 lit 为 null。调试显示 div.Controls 肯定包含 ID 为“litSomeLit”的文字。我的问题是“为什么?”以及“是否有任何方法可以获取特定 ID 的控件,而无需一次手动对 div.Controls[] 进行递归搜索?”

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

Example code:

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

This code fails the assert, because lit is null. Debugging shows that div.Controls definitely contains a literal with ID of "litSomeLit." My questions are "Why?" and "Is there any way to get a control of a specific ID without doing a recursive search of div.Controls[] by hand one element at a time?"

The reason I'm doing things this way is that my actual application is not so straightforward- a method I'm writing is given a complex control with several subcontrols in a number of possible configurations. I need to access a specific control several layers down (eg, the control with ID "txtSpecificControl" might be at StartingControl.Controls[0].Controls[2].Controls[1].Controls[3]). Normally I could just do FindControl("txtSpecificControl"), but that does not seem to work when the controls were just dynamically created (as in the above example code).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

上课铃就是安魂曲 2024-09-23 00:06:44

据我所知,如果不将控件添加到页面,就无法完成我想要完成的任务。如果我不得不猜测,我会说 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;
    }

Near as I can tell, there is no way to do what I'm trying to accomplish without adding the control to the page. If I had to guess, I'd say that FindControl uses the UniqueID property of the control, which generally contains the IDs of all the controls above the current one (eg OuterControlID$LowerControlId$TargetControlID). That would only get generated when the control actually gets added to the page.

Anyway, here's an implementation of recursive depth-first-search FindControl that'll work when the control is not attached to the page yet:

    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;
    }
尴尬癌患者 2024-09-23 00:06:44

将代码更改为

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

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

Change your code to

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

As far as i know FindControl only works when the control is in the visual tree of the page.

第几種人 2024-09-23 00:06:44

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

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

When you confirmed that the control was in the Controls collection, did you do that by inspecting the collection directly? FindControl() may not work in this context.

When you debug the test, is the var lit null? If so, you may have to access the member by item index instead of using the FindControl() method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文