FindControl和INamingContainer

时间:2011-11-17 08:04:18

标签: asp.net findcontrol

我想仔细说出这个问题,所以乐于助人的人不会花时间告诉我我已经知道的信息(我不想浪费他们的时间)。

我想了解FindControl如何在ASP.NET Web应用程序项目中工作(c#文件在标记中被引用为CodeBehind,而不是CodeFile)。

后面的代码有两个位于标记文件之间的文件。例如。 Default.aspx将具有Default.aspx.cs和Default.aspx.designer.cs

如果在页面上放置按钮,则会将其添加到设计器文件中。例如: protected global :: System.Web.UI.WebControls.LinkBut​​ton LinkBut​​ton1;

如果要获取对该控件的引用,它将立即作为Default类的成员提供。例如。 this.LinkBut​​ton1.Text =“点击我”;

如果您查看页面的跟踪,则会根据INamingContainers(此处为Page)的行为为其指定唯一ID:ctl00 $ ContentPlaceHolder1 $ LinkBut​​ton1

我不明白的是为什么语句返回null: Control c = Page.FindControl(“LinkBut​​ton1”);

我意识到这是不必要的,因为按钮已经可用于Default类。这是因为它在Default.aspx.designer.cs文件中显示为成员。

我不理解的是 为什么 返回null。因为Page实现了INamingContainer,并且该按钮的ID与INamingContainer中控件的预期值相关。这不是FindControl找到的那种东西吗?

2 个答案:

答案 0 :(得分:3)

FindControl不是递归的,看起来你有一个中间ContentPlaceHolder1控件,这是一个命名容器,所以这应该有效:Page.FindControl("ContentPlaceHolder1").FindControl("LinkButton1")

答案 1 :(得分:3)

这种行为对我来说是新的,也许是因为我不会尝试搜索直接可访问的控件。我认为这也可能是ASP.NET甚至不允许这样做的原因,因为使用现有引用比找到它(或不是)更快更安全。

  

FindControl方法可用于访问ID不是的控件   在设计时可用。该方法仅搜索页面   立即或顶级容器;它不会递归搜索   控件命名页面中包含的容器。访问   在从属命名容器中控件,调用FindControl   该容器的方法。

http://msdn.microsoft.com/en-us/library/31hxzsdw.aspx

编辑:在我检查此行为后,我注意到null仅在具有MasterPage的页面上使用时才会返回,因为页面中的唯一控件{{1}是MasterPage本身。 那讲得通。当控件位于具有MasterPage的页面的顶层时,您无法保证ID是唯一的,因为其他ContentPages也可能具有此ID的控件,ControlCollection今天可以返回另一个控件而不是明天。

如果您查看要查找的控件的FindControl,您会看到NamingContainer的情况是MasterPage,如果是“普通”页面这是Page本身。

因此,您需要首先获得对MasterPage的ContentPlaceholder的引用,然后才能通过FindControl找到控件:

ContentPlaceHolder

http://msdn.microsoft.com/en-us/library/xxwa0ff0.aspx

相关问题