随心所欲

做个幸福的人
posts - 147, comments - 1402, trackbacks - 28, articles - 0
  博客园 :: 首页 :: 新随笔 ::  :: 订阅 订阅 :: 管理

以前我就曾经写过一个关于MasterPage里面使用this.FindControl()函数的问题。

http://www.cnblogs.com/dlwang2002/archive/2006/07/09/446643.html

当时通过其他方式解决了,但是今天又遇到了。在google上找到了一篇文章http://west-wind.com/WebLog/posts/5127.aspx说的很对,能够解决这个问题

 

在没有使用MasterPage之前,页面this访问到的对象就是他自己,所以使用this,FindControl也就没什么问题。

但是使用MasterPage之后,this.Control.Count=1,就只有一个。跟踪一下:   this.Controls[0]      {ASP.module_mp1_master}       System.Web.UI.Control {ASP.module_mp1_master} .

也就是说,加入masterPage之后他的控件的顺序就变了。(以前看过一个在asp.net1.1下的MasterPage实现,也是类似的方式,重新组织控件)。这就是问题所在。

 

解决方法:

把原来这样的使用:

protected void AssignControls()

{

    
this.lblError = this.FindControl("lblError"as Label;

    
this.dgItemList = this.FindControl("dgItemList"as DataGrid;

}


变成这样调用:

protected void AssignControls()

{

    
this.lblError = this.Master.FindControl("Content").FindControl("lblError"as Label;

    
this.dgItemList = this.Master.FindControl("Content").FindControl("dgItemList"as DataGrid;

}



也就是说,先使用this.Master.FindControl("Content")来找到在MasterPage上相对的位置,然后再按照以前的调用方式就可以了。

 

或者使用这个函数(这三个函数都来自原作者Rick Strahl

public static Control FindControlRecursive(Control Root, string Id)

{

    
if (Root.ID == Id)

        
return Root;

 

    
foreach (Control Ctl in Root.Controls)

    
{

        Control FoundCtl 
= FindControlRecursive(Ctl, Id);

        
if (FoundCtl != null)

            
return FoundCtl;

    }


 

    
return null;

}


 

Feedback

#1楼    回复  引用  查看    

2006-12-21 12:37 by Cat Chen      
其实你只要打开页面的Trace功能,就能够看到完整的控件树结构,也就知道如何去FindControl了。

FindControlRecursive函数是要谨慎使用的,因为控件树中可以出现多个控件共用一个ID(UniqueID不同),递归寻找返回的是递归与迭代中遇到的第一个该ID的控件,你除非确认整个树中不可能出现其他控件和你要寻找的控件同ID,否则你不能确保返回的控件就一定是你期望的那个。

#2楼 [楼主]   回复  引用  查看    

2006-12-21 13:03 by 随心所欲      
@Cat Chen
是的,可以看出来控件树,但还是没办法。我尝试过不少方法
this.Master.FindControl ("PlaceHolder1")
this.FindControl("ctl00_view_PlaceHolder1",4)
this.Master.FindControl("PlaceHolder1")
this.Form.FindControl("PlaceHolder1")
this.Control[0].FindControl
this.Maser.Page.FindControl
……
花招用尽,也没找到。

#3楼    回复  引用  查看    

2006-12-21 13:31 by Jeffrey Zhao      
FindControlRecursive不是个好方法……FindControl是要有INamingContainer做保证的……

#4楼 [楼主]   回复  引用  查看    

2006-12-21 13:47 by 随心所欲      
@Jeffrey Zhao
INamingContainer? 可以说的详细一点么?
第二个重载FindControl(id,offset)里面的参数是个int,只是一个层次吧,可以利用么?

#5楼    回复  引用  查看    

2006-12-21 15:22 by Cat Chen      
@随心所欲
你看到有下划线分开的ClientID,那就是INamingContainer造成的。

例如你用一个Master吧,里面两个Content,它们内部都有一个LinkButton1,那么怎么区分呢?因为Content是INamingContainer,所以就会让两个LinkButton1分别命名为Content1_LinkButton1和Content2_LinkButton2。我这个例子可能说得不严谨,不过INamingContainer大概就是这样运作的。

接着,你在Master里面找LinkButton1,你会找不到。递归查找,你没办法保证返回的那个来自于Content1还是Content2(实际上能保证,但理论上你不能依赖于这种现实)。

#6楼 [楼主]   回复  引用  查看    

2006-12-21 18:10 by 随心所欲      
@Cat Chen
原来如此。看来FindControl的第二个重载就是设定offset几个INamingContainer了。
递归实现确有不合适的地方。

#7楼    回复  引用  查看    

2006-12-22 22:45 by Cat Chen      
@随心所欲
offset应该是几层child吧?跨越INamingContainer是不允许的,因为不同的INamingContainer中可以存在相同的ID。

#8楼 [楼主]   回复  引用  查看    

2006-12-23 08:42 by 随心所欲      
@Cat Chen
多谢!

#9楼    回复  引用    

2007-03-13 19:38 by 茄子 [未注册用户]
不错,借鉴

#10楼    回复  引用    

2007-11-15 17:07 by kuan [未注册用户]
学习了




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》

相关文章:

相关链接:
 
Google