服务器控件的 ID,ClientID,UniqueID 的区别

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等

你可能感兴趣的:(client)