欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 » ASP.Net » 正文

热门阅读

.Net自定义控件之INamingContainer接口详解

创建时间:2012年01月01日 20:21  阅读次数:(5832)
分享到:
INamingContainer是一个没有任何方法和属性的接口,了解这一接口,我们首先要清楚.net中服务器控件的唯一标志:控件ID。

作为控件使用者来说,使用的最多的应该就是控件的ID了,其实任何一个服务器控件都有三个标识,分别是ClientID、ID与UniqueID。

三个标识解释如下:
ClientID:客户端ID,就是我们在页面前台利用js取控件值时所用到的控件标识。
ID:我们在使用控件时为它赋于的一个标识,即我们给它命名的ID,而这个ID无论是在客户端还是在服务器端都不会使用,它只是方便我们编程而已。
UniqueID:服务端控件的标识,.net在服务器端搜索控件时,就是使用UniqueID。

在明白了上面三个ID后,我们还需要知道,在一个页面中,是不允许出现相同的ID。无论是ClientID,还是ID与UniqueID。

那么,.net是如何来保证一个页面中所有的控件都不会产生相同的ID呢?比如,在一个复合控件中,我们为一个子控件设置了ID为button1。然后我们在页面中拖放了这个复合控件,那么.net在生成html页时,就会生成一个ID为button1的控件,如果我们在这个页面中再拖放一个这个复合控件,按照理解,那么在生成html页时,会再生成一个ID为button1的控件,这样,ClientID就重复了,而在asp.net,这是不允许的。

那么,.net中是如何来处理这个问题呢?这时INamingContainer接口就上场了。

INamingContainer是一个没有任何方法和属性的接口,当自定义控件实现这个接口时,asp.net页框架将在这个控件下创建一个命名范围,为这个控件的所有子控件的ID加上"父控件+分隔符"这样的前缀,这就可以使的在同一个页面中,所有的控件ID都不重复了。

我们可以用一个例子来验证这个问题:
先创建一个名为ServerControl1的复合控件,代码如下:
namespace INamingContainerControl
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server ></{0}:ServerControl1 >")]
public class ServerControl1 : WebControl
{
protected override void CreateChildControls()
{
TextBox textbox = new TextBox();
textbox.ID = "textbox1";
this.Controls.Add(textbox);
}
}
}

可以看到,这个复合控件并没有继承INamingContainer接口,然后我们在一个aspx页面中放两个ServerControl1控件,再看这个aspx页面生成的html代码如下:
<form name="form1" method="post" action="Default.aspx" id="form1" >
<div >
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMjYwNjA1NjY2ZGRfWPmkcbCTQZzDM9Iy18YcRqkh4w==" / >
</div >

<div >
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwL56q+LAQKsyrLrBgKsyrLrBpkl+pkIRqjolfXhcUP62HYpKeUo" / >
</div >

<span id="ServerControl11" ><input name="textbox1" type="text" id="textbox1" / ></span >
<span id="ServerControl12" ><input name="textbox1" type="text" id="textbox1" / ></span >


</form >

可以看到,页面中生成了两个id等于textbox1的控件。这是不允许的,因为如果存在两个id相同的控件时,我们在使用js的documnet.getElementById()方法取控件值时,就可能会取不正确的值。

下面我们修改ServerControl1控件,使之继承INamingContainer接口,代码如下:
namespace INamingContainerControl
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server ></{0}:ServerControl1 >")]
public class ServerControl1 : WebControl,INamingContainer
{
protected override void CreateChildControls()
{
TextBox textbox = new TextBox();
textbox.ID = "textbox1";
this.Controls.Add(textbox);
}
}
}

可以看到,这段代码与上段代码相比,只是继承了INamingContainer接口,其它没有做任何改变。然后我们同样在一个aspx页面中放入两个ServerControl1控件,再看这个页面生成的Html代码如下:
<form name="form1" method="post" action="Default.aspx" id="form1" >
<div >
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMjYwNjA1NjY2ZGRfWPmkcbCTQZzDM9Iy18YcRqkh4w==" / >
</div >

<div >
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwL56q+LAQL5/Pb7DQKUjsuiDnCm+0IPVDI3HZWQs46aZEI5tpWD" / >
</div >

<span id="ServerControl11" ><input name="ServerControl11$textbox1" type="text" id="ServerControl11_textbox1" / ></span >
<span id="ServerControl12" ><input name="ServerControl12$textbox1" type="text" id="ServerControl12_textbox1" / ></span >


</form >

可以看到,aspx页面中ServerControl1控件中的TextBox控件ID前都自动加上了前缀"ServerControl11_",name前也自动加上了"ServerControl11$"的前缀,另一个ServerControl2控件中的TextBox控件ID分别加上了"ServerControl12_"与"ServerControl12$"的前缀,这样就保证了在同一个aspx页面中,每个控件都具有不同的id与name。

总结:InamingContainer接口的作用就是为了解决一个页面中在使用多个自定义控件时ID可能会重复的问题。
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 29+2=? 的结果(结果是:31)
结  果: