转:服务器控件的 ID,ClientID,UniqueID 的区别
动态加载用户控件的怪问题
动态加载用户控件的时候,会因为调用一些控件的一些属性和方法而造成控件命名混乱.
因为add 一个用户控件或者 loadcontrol 的时候
如果没有指定控件的id,clientid,那么它会初始id为:"_ctl0"
如果在把用户控件 add到页面之前调用了一下用户控件里面的 TextBox1.ClientID-->会导致用户控件开始命名
因为这时候用户控件这时候还没有被add到页面,所以这时候生成的 ClientID 肯定不会有父控件的名称.
而且子控件的初始id为:"_ctl0",接着往下,只要是没有被命名的 _ctl1,_ctl2......
这样当用户控件真正的被 add到页面时 同样用户控件也没有指定控件的id,那么这个用户控件的 id就会被
初始id为:"_ctl0"
到这我们应该看出问题了.
子控件与父控件的id重复了.从而导致了用户控件里面的 TextBox1 的viewstate 不能被恢复,按钮事件不能被触发等等一系列怪问题.
而如果先把用户控件 add进入页面,然后再做操作.则用户控件里面的控件命名变为:
用户控件
id type
_ctl0 ASP.webusercontrol1_ascx
_ctl0:_ctl0 System.Web.UI.LiteralControl
_ctl0:Button2 System.Web.UI.WebControls.Button
_ctl0:_ctl1 System.Web.UI.LiteralControl
*********************************************************
1简述
ID是设计的时候所指定的ID。有我们在写代码的时候指定的.是我们分配给服务器控件的编程标识符。我们常常在服务器端使用方法findcontrol(controlid) 来寻找控件.这时候controlid指的就是这个ID.
ClientID是由ASP.Net生成的服务器控件标识符,当这个控件生成到客户端页面时候,需要在客户端访问时候用的。 ClientID 通过将子控件的父控件的 UniqueID 值与控件的 ID 值连接生成,各个部分之间以下划线 _ 连接。
如我们常常用到的js脚本:
var searchID = '<%=btnSearch.ClientID%>';
document.getElementById(searchID).click();
获取btnSearch 的ClientID,在client中呈现为html元素的id属性
UniqueID 服 务器控件的唯一的、分层的形式限定的标识符。 是当需要参与服务端回传的时候用的。当将控件放置到重复控件(Repeater、DataList和DataGrid)中时,将可能生成多个服务器端的控 件,这就需要区分服务器端的各个控件,以使它们的 ID 属性不冲突。UniqueID 通过将子控件的父控件的 UniqueID 值与控件的 ID 值连接生成,各个部分之间以 IdSeparator 属性指定的字符连接。默认情况下, IdSeparator 属性为冒号字符 (:)。此属性为在 .Net Framework2.0种新增加。 在client中呈现为html元素的name属性
2生成原理
public virtual string ClientID


{
get

{
this.EnsureID();
string uniqueID = this.UniqueID;
if ((uniqueID != null) && (uniqueID.IndexOf(this.IdSeparator) >= 0))

{
return uniqueID.Replace(this.IdSeparator, '_');
}
return uniqueID;
}
}
protected void EnsureID()


{
if (this._namingContainer != null)

{
if (this._id == null)

{
this.GenerateAutomaticID();
}
this.flags.Set(0x800);
}
}
ClientID就是将UniqueID中的IdSeparator 替换为”_”。
public virtual string UniqueID


{
get

{
if (this._cachedUniqueID == null)

{
Control namingContainer = this.NamingContainer;
if (namingContainer == null)

{
return this._id;
}
if (this._id == null)

{
this.GenerateAutomaticID();
}
if (this.Page == namingContainer)

{
this._cachedUniqueID = this._id;
}
else

{
string uniqueIDPrefix = namingContainer.GetUniqueIDPrefix();
if (uniqueIDPrefix.Length == 0)

{
return this._id;
}
this._cachedUniqueID = uniqueIDPrefix + this._id;
}
}
return this._cachedUniqueID;
}
}
if (this._id == null)
{
this.GenerateAutomaticID();
}
//对控件编号初始化
if (this.Page == namingContainer)
{
this._cachedUniqueID = this._id;
}
//当前控件的父控件是Page,如一些用户控件之类的,则它的UniqueID就是控件的ID。
else
{
string uniqueIDPrefix = namingContainer.GetUniqueIDPrefix();
if (uniqueIDPrefix.Length == 0)
{
return this._id;
}
this._cachedUniqueID = uniqueIDPrefix + this._id;//前缀+ID 作为当前控件的UniqueID
}
//当前控件父控件不是父控件而是像Repeater、DataList和DataGrid,已经table等的另一种容器控件
//那我们先根据 GetUniqueIDPrefix() 方法 取得父控件UniqueID+分隔符($)作为当前控件的UniqueID前缀。
//这里要注意的是如果这时候子控件还没有被add到父控件里面,或者父控件的ID还没有,那么它的UniqueID就是它本身的ID。有父控件就前缀加ID
GenerateAutomaticID()
private void GenerateAutomaticID()
{
this.flags.Set(0x200000);
this._namingContainer.EnsureOccasionalFields();
int index = this._namingContainer._occasionalFields.NamedControlsID++;
if (this.EnableLegacyRendering)
{
this._id = "_ctl" + index.ToString(NumberFormatInfo.InvariantInfo);
}
else if (index < 0x80)
{
this._id = automaticIDs[index];
}
else
{
this._id = "ctl" + index.ToString(NumberFormatInfo.InvariantInfo);
}
this._namingContainer.DirtyNameTable();
}
//对控件编号初始化
GetUniqueIDPrefix函数
internal virtual string GetUniqueIDPrefix()
{
this.EnsureOccasionalFields();
if (this._occasionalFields.UniqueIDPrefix == null)
{
string uniqueID = this.UniqueID;
if (!string.IsNullOrEmpty(uniqueID))
{
this._occasionalFields.UniqueIDPrefix = uniqueID + this.IdSeparator;
}
else
{
this._occasionalFields.UniqueIDPrefix = string.Empty;
}
}
return this._occasionalFields.UniqueIDPrefix;
}
3
this.Controls.Add 这个方法对 UniqueID的影响.
这时候控件会加上父控件的UniqueID.
这个问题可以参照我
动态加载用户控件的怪问题 http://www.cnblogs.com/kasafuma/archive/2008/04/09/1145390.html
因为先在用户控件里面调用了 子控件的clientID, 这时候用户控件还没有被加到 页面.
所以子控件的clientID 为clt0.而当用户控件被add到页面的时候它的ID又会被初始化为clt0,造成ID的重复.
所以我们在添加用户控件时先add后再调用它里面的一些方法和属性.如clienID等
转:服务器控件的 ID,ClientID,UniqueID 的区别的更多相关文章
- asp.net 服务器控件的 ID,ClientID,UniqueID 的区别
1.简述 ID是设计的时候自己所指定的ID,是我们分配给服务器控件的编程标识符,我们常常使用this.controlid来寻找控件,那么这个controlid就是这里所说的ID. ClientID是由 ...
- id,clientid 和 uniqueid 的区别
一. ID是设计的时候所指定的ID. ClientID是当这个控件生成到客户端页面时候,需要在客户端访问时候用的. UniqueID是当需要参与服务端回传的时候用的. 备注:当控件是子控件的时候(例如 ...
- 当使用母版页时JavaScript客户端获取服务器控件的Id
当使用MasterPage.UserControl等容器时,为了避免控件的重复命名,asp.net会自动将容器中的控件生成一个ClientID(Control Tree中的可生成,否则不会生成). J ...
- html元素中id和name的区别
可以说几乎每个做过Web开发的人都问过,到底元素的ID和Name有什么区别阿?为什么有了ID还要有Name呢?! 而同样我们也可以得到最classical的答案:ID就像是一个人的身份证号码,而Nam ...
- html中元素的id和name的区别(2016-1-22)
HTML中元素的Id和Name属性区别 一直以来一直以为在html中,name和id没什么区别,今天遇到一个坑才发现(PHP获取不到表单数据,原因:元素没有name,只定义了id),这两者差别还是很大 ...
- form表单中的id 与name的区别
以前经常写form表单时,不写id和name,总觉得没有什么用.后来一看后台套完的页面发现,他们都补上name,不知道所以然,就查了一下资料,吓我一跳,要是照我那样写根本不会有数据传到服务器.原来表单 ...
- javascript querySelector和getElementById通过id获取元素的区别
querySelector和getElementById通过id获取元素的区别 <!DOCTYPE html> <html> <head> <meta cha ...
- id和class的区别
id和class是定义css样式用到的,不同的是定义样式时的写法不一样,使用id选择样式时,定义的格式为 #main{width:20px;} ,使用class时用到的是 .main{width:20 ...
- form表单中id与name的区别
以前经常写form表单时,不写id和name,总觉得没有什么用.后来一看后台套完的页面发现,他们都补上name,不知道所以然,就查了一下资料,吓我一跳,要是照我那样写根本不会有数据传到服务器.原来表单 ...
随机推荐
- wordpress添加子主题
使用子主题,可以继承父主题的所有功能,同时避免因为直接使用父主题在父主题升级时造成文件丢失的情况. 子主题的创建很简单: 1.首先在主题文件夹下(wp-content\themes)建立一个文件夹,用 ...
- mysql 无法启动1067
关键字:mysql无法启动办事,mysql卡死,InnoDB"" registration as a STORAGE ENGINE failed.Unknown/unsupport ...
- Js练习题之查找字符串中出现最多的字符和个数
如sssfgtdfssddfsssfssss,出现最多的字符是s,出现了12次 传统写法 分析: 1.准备一个空的json,通过循环字符串的每个字符来看,如果json里没有这个字符,就在json里创建 ...
- Admob(6.12.x)符号未定义错误的解决方法(IOS)
在升级Admob的SDK版本到6.12.x时, 按照官方文档操作(https://developers.google.com/mobile-ads-sdk/docs/#ios), 添加如下framew ...
- HDU 1828 扫描线(矩形周长并)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- LA 5059 - Playing With Stones
博弈 SG 由于每个a太大,没有办法递推,但是可以找规律 a为偶数 SG(a)=a/2 a为奇数 SG(a)=SG(a/2) 代码: #include <iostream> #inc ...
- CentOS下编译安装MySQL 5.6.21
一.编译安装MySQL前的准备工作 安装编译源码所需的工具和库 yum install gcc gcc-c++ ncurses-devel perl 安装cmake:http://www.cnblog ...
- 编绎openssl杂记(window)
Window 下 OpenSSL 编绎过程 1. 下载 ActivePerl-5.12.4.1205 , openssl-0.9.8 , 配置Perl环境变量 , 解压openssl-0.9.82. ...
- 【未完成0.0】Noip2012提高组day2 解题报告
第一次写一套题的解题报告,感觉会比较长.(更新中Loading....):) 题目: 第一题:同余方程 描述 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. 格式 输入格式 输入只有一 ...
- WebBrowers & HtmlViewers collection
WebBrowers & HtmlViewers collection 浏览: 加入我的收藏 楼主: THtmlViewerhttps://github.com/BerndGabriel/Ht ...