INamingContainer接口解决多个自定义控件ID冲突

CreateChildControls方法一般用于创建组合控件,在此方法中可以创建多个自己需要的控件,进行实例化,赋值等等.
我们创建个复合控件,如下:
public class CompositeCtl: WebControl
    {
        
protected override void CreateChildControls()
        {
            TextBox textbox 
= new TextBox();
            textbox.ID 
= "txt";
            
this.Controls.Add(textbox);

            Button button 
= new Button();
            button.ID 
= "btnOk";
            button.Text 
= "Ok";
            
this.Controls.Add(button);
        }
    }

在客户端,我们引用2遍我们的这个自定义控件:
<myCtl:INamingConatinerControl ID="namingCtl1" runat="server" />
        
<br />
        
<myCtl:INamingConatinerControl ID="namingCtl2" runat="server" />

生成的HTML代码如下:
<span id="namingCtl1"><input name="txt" type="text" id="txt" /><input type="submit" name="btnOk" value="Ok" id="btnOk" /></span>
        
<br />
        
<span id="namingCtl2"><input name="txt" type="text" id="txt" /><input type="submit" name="btnOk" value="Ok" id="btnOk" /></span>

上面我们可以看到比较严重的问题是:
2个文本框和按钮的客户端id居然是一样的,这样我们无法利用客户端的JS语句getElementById来得到某个具体的
文本框或者按钮.

解决办法:
让自定义控件实现INamingContainer(命名容器)接口,其他什么都不用做,代码会自动为以控件的ID作为前缀进行拼接.

控件正式代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace BlogControl.Basic
{
    
public class INamingConatinerControl : WebControl,INamingContainer
    {
        
protected override void CreateChildControls()
        {
            TextBox textbox 
= new TextBox();
            textbox.ID 
= "txt";
            
this.Controls.Add(textbox);

            Button button 
= new Button();
            button.ID 
= "btnOk";
            button.Text 
= "Ok";
            
this.Controls.Add(button);
        }
    }
}

这样生成的HTML代码如下:
<span id="namingCtl1"><input name="namingCtl1$txt" type="text" id="namingCtl1_txt" /><input type="submit" name="namingCtl1$btnOk" value="Ok" id="namingCtl1_btnOk" /></span>
        
<br />
        
<span id="namingCtl2"><input name="namingCtl2$txt" type="text" id="namingCtl2_txt" /><input type="submit" name="namingCtl2$btnOk" value="Ok" id="namingCtl2_btnOk" /></span>

我们可以看到:
服务器端的name: 控件名 + $ + ID
客户端ID:           控件名 + _  + ID
区别在于连接的符号不同.

这里我们提一下控件的3种ID:
1) ID - 就是我们给它命名的 ID
2) UniqueID - 控件的服务器端ID (生成HTML后的name)
3) ClientID   - 控件的客户端ID  (生成HTML后的id)

最后我们要提一下的是:
如果控件继承了 CompositeControl,就不需要再实现INamingContainer接口了,因为
CompositeControl本身就实现了该接口.


原文地址:https://www.cnblogs.com/davidgu/p/1553426.html