解决Page.FindControl方法找不到指定控件 转

上一篇用户控件之间事件调用方法里用到了Page.FindControl方法, 结果里面的例子是可以的, 我用到了网站里就出错了, 出现了"未将对象引用设置到对象的实例", 一般是对象没有初始化, 下面是解决办法

转自http://blog.csdn.net/mengkun2010

"

1. 首先来了解以下FindControl的工作原理:

在ASP.NET 2.0中,引入了MasterPage的机制,在当前页使用MasterPage的情况下,放在 ContentPlaceholder1这样的内容页的控件无法用Page.FindControl来查找,原因何在?

MSDN对FindControl的解释:在当前的命名容器中搜索带指定 id 参数的服务器控件

这里有一篇文章阐述阐述FindControl方法和INamingContainers接口:http://www.odetocode.com/Articles/116.aspx

FindControl方法是在当前naming container查找指定ControlID对应的控件,该naming container是一个实现了INamingContainer接口的对象。

可以在该页的页指令中添加 Trace=Ture 指令来跟踪页面输出查看控件树。一个页面的控件树中,Page对象必然是顶级的naming container,但绝非必然是唯一的naming container。譬如当有GridView存在的话,GridView其实也是一个naming container,要找GridView中的一个ControlID,就不能用Page.FindControl,而得用[GridView对象].FindControl方法。

很多时候,因为是动态控件,明知道是在同一个naming container中,但不知道该naming container是什么对象,一个控件要找到另一个控件,可以用this.Parent.FindControl方法。

2. 解决问题:

因为使用MasterPage后,你再用Page.FindControl不可能找到的,这没什么疑问,因此正确的方法是你先找到此控件的naming container,这里也就是ContentPlaceHolder#的ID,然后在去找你的控件,比如:Page.Master.FindControl("ContentPlaceHolder1").FindControl("TextBox1")。

3. 深度分析:

显然在第二步里面我们给问题解决了,但是仔细分析,不难发现这个解决方案本身存在着另外一个问题,即:如果ContentPlaceHolder1这个ID改变了,那么你的CODE就不能用了,也要改变。

一个跟更好的解决方法是:

TextBox[] tbx = new TextBox[] { this.TextBox1,this.TextBox2......}

然后使用tbx[index]来作为你要的控件。

"

以及csdn里的一篇帖子http://topic.csdn.net/u/20100820/14/836ebf37-3989-4868-98c5-1795de7f5c73.html

"

  • 解决Page.FindControl方法找不到指定控件 转
  • gongshunkai
  • (gongshunkai)
  • 等 级:解决Page.FindControl方法找不到指定控件 转
  • 结帖率:
楼主发表于:2010-08-20 14:31:18
((LinkButton)Page.FindControl("LinkButton"+i.ToString())).CssClass = "selectTag2323"; 报错:未将对象引用设置到对象的实例


网上查了下:

譬如最普遍的,在ASP.NET 2.0中,引入了MasterPage的机制,在当前页使用MasterPage的情况下,当前页也产生了类似ContentPlaceholder1这样的naming container,这时查找当前页的控件,也不能使用Page.FindControl方法,而得要用ContentPlaceholder1.FindControl方法。  

很多时候,因为是动态控件,明知道是在同一个naming container中,但不知道该naming container是什么对象,一个控件要找到另一个控件,可以用this.Parent.FindControl方法。  


我的LinkButton是在 <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server"> 里面的

我改成 ((LinkButton)ContentPlaceHolder2.FindControl("LinkButton"+i.ToString())).CssClass = "selectTag2323"; 报错:当前上下文中不存在名称“ContentPlaceHolder2”

我的页面结构是这样的:母板页 - 子母板页 - 当前页

请教应该如何解决啊?
#1楼 得分:0回复于:2010-08-20 14:42:39
Page.Master.Master.FindControl("xxxx").
#2楼 得分:0回复于:2010-08-20 14:58:58
通过this.Master获取直系Master,让后this.Master.Master可以获取父Master
Master.Master.FindControl("")
TextBox textBoxFind = (TextBox)this.Page.Master.FindControl(masterPageContentPlaceHolderID).FindControl("");   
#13楼 得分:0回复于:2010-08-20 20:47:29
不是跟你说了吗?》???Page.Master.Master.FindControl 你怎么不试试呢??

LinkButton lb = Page.Master.Master.FindControl("ContentPlaceHolder1").FindControl("ContentPlaceHolder2").FindControl("LinkButton1") as LinkButton;
lb.Text = "yyyyy";
#14楼 得分:0回复于:2010-08-20 20:52:10
严格测试过程如下:为创建方便,创建为单一文件
1,parent.master文件:
HTML code
<%@ Master Language="C#" AutoEventWireup="true"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <asp:ContentPlaceHolder ID="head" runat="server"> </asp:ContentPlaceHolder> </head> <body> <form id="form1" runat="server"> <h1>Parent 模板页</h1> <div> <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </div> </form> </body> </html>


2,child.master
HTML code
<%@ Master Language="C#" AutoEventWireup="true" MasterPageFile="~/parent.master"%> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> <h2>Child 模板页</h2> <asp:ContentPlaceHolder id="ContentPlaceHolder2" runat="server"> </asp:ContentPlaceHolder> </asp:Content>


3,内容页
HTML code
<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/child.master" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { for (int i = 1; i < 6; i++) { LinkButton lb = Page.Master.Master.FindControl("ContentPlaceHolder1").FindControl("ContentPlaceHolder2").FindControl("LinkButton" + i.ToString()) as LinkButton; lb.Text = "新的值" + i.ToString(); } } </script> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" runat="Server"> <h3>内容页内容</h3> <asp:LinkButton ID="LinkButton1" runat="server" Text="孟宪会"></asp:LinkButton> <asp:LinkButton ID="LinkButton2" runat="server" Text="孟宪会"></asp:LinkButton> <asp:LinkButton ID="LinkButton3" runat="server" Text="孟宪会"></asp:LinkButton> <asp:LinkButton ID="LinkButton4" runat="server" Text="孟宪会"></asp:LinkButton> <asp:LinkButton ID="LinkButton5" runat="server" Text="孟宪会"></asp:LinkButton> </asp:Content>

"

孟爷怒了..

我的网站里用了一个母版页, 所以我的应该这样写, 顺着元素名一步一步找到

BJshitishu tname = Page.Master.FindControl("MainContent").FindControl("BJshitishu1") as BJshitishu;

你可能感兴趣的:(find)