c# - Control.UniqueId 是什么时候创建的?

标签 c# asp.net .net-3.5 page-lifecycle unique-id

有人知道控件的 UniqueId 是什么时候分配的吗?

现在我的 Page_Init 中有一些基于 UniqueId 的代码。但是,根据某些业务逻辑,我可能需要在此之前重新安排页面的控件层次结构。

所以,我的主要问题是,何时分配 UniqueId?我是否可以重新安排 Page_PreInit() 中的层次结构,以便当我的代码在 Page_Init() 中触发时,我将分配正确的 UniqueId?

最佳答案

为了回答这个问题,我写了一个小的代码隐藏,它记录了每个事件的控件的 UniqueID 属性值:

  • 初始化前
  • 初始化
  • 初始化完成
  • 预加载
  • 加载
  • 加载完成
  • 预渲染
  • 预渲染完成

例如,最后一个事件处理程序如下所示:

protected void Page_PreRenderComplete(object sender, EventArgs e)
{
    _uniqueIdValues.Add(
        new Tuple<string, string>("PreRenderComplete", MyControl.UniqueID));
}

然后,我在 Unload 事件中设置断点并使用 Visual Studio 的即时窗口打印出记录的值:

_uniqueIdValues.ToArray()
{System.Tuple<string,string>[8]}
    [0]: {(PreInit, MyControl)}
    [1]: {(Init, MyControl)}
    [2]: {(InitComplete, MyControl)}
    [3]: {(PreLoad, MyControl)}
    [4]: {(Load, MyControl)}
    [5]: {(LoadComplete, MyControl)}
    [6]: {(PreRender, MyControl)}
    [7]: {(PreRenderComplete, MyControl)}

似乎每个事件的 UniqueID 都设置为字符串“MyControl”(实际上是我在 ASPX 标记中为控件指定的 ID 属性)。看起来 @Rewinder 来自 MSDN 的回答是正确的。这些是在触发任何 ASP.NET 页面级事件之前设置的。

编辑:

如果我们查看 System.Web.UI.Control 的 .NET 3.5 引用源 (http://referencesource.microsoft.com/),我们可以看到 UniqueID 的返回值是在访问属性时计算的. UniqueID 属性如下所示:

public virtual string UniqueID { 
    get { 
        if (_cachedUniqueID != null) {
            return _cachedUniqueID; 
        }

        Control namingContainer = NamingContainer;
        if (namingContainer != null) { 
            // if the ID is null at this point, we need to have one created and the control added to the
            // naming container. 
            if (_id == null) { 
                GenerateAutomaticID();
            } 

            if (Page == namingContainer) {
                _cachedUniqueID = _id;
            } 
            else {
                string uniqueIDPrefix = namingContainer.GetUniqueIDPrefix(); 
                if (uniqueIDPrefix.Length == 0) { 
                    // In this case, it is probably a naming container that is not sited, so we don't want to cache it
                    return _id; 
                }
                else {
                    _cachedUniqueID = uniqueIDPrefix + _id;
                } 
            }

            return _cachedUniqueID; 
        }
        else { 
            // no naming container
            return _id;
        }
    } 
}

并且,当命名容器更改时调用以下方法。 ClearCachedUniqueIDRecursive 方法重置 _cachedUniqueID 字段的值,以便在下次调用 UniqueID 属性时重新生成它。

private void UpdateNamingContainer(Control namingContainer) {
    // Remove the cached uniqueID if the control already had a namingcontainer
    // and the namingcontainer is changed. 
    if (_namingContainer != null && _namingContainer != namingContainer) {
        ClearCachedUniqueIDRecursive(); 
    } 

    _namingContainer = namingContainer; 
}

关于c# - Control.UniqueId 是什么时候创建的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5472874/

相关文章:

c# - 在两个函数上调用委托(delegate)

c# - LoadLibrary() 在 C# 中返回 0

c# - 根据KeyWord从XML中提取一个节点

asp.net - URLRewriter 查询字符串中的 & 符号

c# - 如何在 SelectedIndexChanged 触发事件之前获取 DropDownList 中的上一个项目

c# - 处理无效的 XML 十六进制字符

c# - RabbitMQ 客户端连接到多个主机

c# - 如果可能的话,如何使方法的返回值可选?

c# - 在通用列表的 ForEach() 的 lambda 表达式中使用条件运算符?

c# - 组合多个 SubSonic.Where 过滤器