.Net自定义控件之INamingContainer接口详解
来源:互联网 发布:java无参方法构造 编辑:程序博客网 时间:2024/05/01 17:51
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的复合控件,代码如下:
可以看到,这个复合控件并没有继承INamingContainer接口,然后我们在一个aspx页面中放两个ServerControl1控件,再看这个aspx页面生成的html代码如下:
可以看到,页面中生成了两个id等于textbox1的控件。这是不允许的,因为如果存在两个id相同的控件时,我们在使用js的documnet.getElementById()方法取控件值时,就可能会取不正确的值。
下面我们修改ServerControl1控件,使之继承INamingContainer接口,代码如下:
可以看到,这段代码与上段代码相比,只是继承了INamingContainer接口,其它没有做任何改变。然后我们同样在一个aspx页面中放入两个ServerControl1控件,再看这个页面生成的Html代码如下:
可以看到,aspx页面中ServerControl1控件中的TextBox控件ID前都自动加上了前缀"ServerControl11_",name前也自动加上了"ServerControl11$"的前缀,另一个ServerControl2控件中的TextBox控件ID分别加上了"ServerControl12_"与"ServerControl12$"的前缀,这样就保证了在同一个aspx页面中,每个控件都具有不同的id与name。
总结:InamingContainer接口的作用就是为了解决一个页面中在使用多个自定义控件时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);
}
}
}
{
[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 >
<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);
}
}
}
{
[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 >
<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可能会重复的问题。
0 0
- .Net自定义控件之INamingContainer接口详解
- asp.net 自定义组合控件必须继承INamingContainer接口原因分析
- INamingContainer接口的另外作用
- ASP.Net中,PlaceHolder、Panel等控件未实现INamingContainer,导致FindControl无效
- 创建服务器控件时INamingContainer的作用
- 自定义控件之复合控件详解
- asp.net WebForm之用户自定义控件
- android自定义控件之Dialog详解
- Android自定义控件热身之Scroller详解
- 自定义控件之绘图篇:drawText详解
- 自定义控件之二阶贝塞尔曲线方法详解
- 自定义View控件之onMeasure方法详解
- 自定义控件之绘图篇:drawText()详解
- 自定义控件 接口
- ASP.NET自定义控件之Tips提示信息控件 (一)
- 自定义asp.net控件开发之(一)-显示控件内容
- 自定义asp.net控件开发之(五)-UpdownPanel控件实例
- ASP.NET技巧:GridView控件自定义分页详解第一页
- 我的学习之旅 keyboard.h和keyboard.c
- Android一键锁屏程序实例
- 杭电 HDU 1215 七夕节
- Protocol Layers in Computer Network
- oc 的第四天
- .Net自定义控件之INamingContainer接口详解
- Using Objective-C achieve the stack structure.(用Objective-C实现堆栈)
- UVA - 12589(learning vector dp)
- android 输入框 XML 设置于代码设置异同
- 海盗分宝石
- GetFileName()有效最大文件长度不是1085
- iOS集成构建总结 (libimobiledevice)
- Stanford机器学习课程笔记2-高斯判别分析与朴素贝叶斯
- 在创建触发器时出现不能在 'inserted' 表和 'deleted' 表中使用 text、ntext 或 image 列