Control.UniqueId 何时创建?
Posted
技术标签:
【中文标题】Control.UniqueId 何时创建?【英文标题】:When is Control.UniqueId created? 【发布时间】:2011-07-25 06:41:05 【问题描述】:有人知道何时分配控件的 UniqueId 吗?
现在我的 Page_Init 中有一些基于 UniqueId 的代码。但是,根据某些业务逻辑,我可能需要在此之前重新排列页面的控制层次结构。
所以,我的主要问题是,UniqueId 是什么时候分配的?我是否可以重新排列 Page_PreInit() 中的层次结构,以便当我的代码在 Page_Init() 中触发时,我将分配正确的 UniqueId?
【问题讨论】:
你为什么要依赖UniqueId
- Tag
不是更好吗?
【参考方案1】:
为了回答这个问题,我编写了一个小代码隐藏,用于记录每个事件的控件的 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 属性)。 MSDN 中@Rewinder 的回答似乎是正确的。这些是在触发任何 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;
【讨论】:
有趣的是,如果我检查控件的 UniqueID 的值,然后更改该控件的父容器,当我再次检查 UniqueID 时,它会更新为新的层次结构。 查看 System.Web.UI.Control 的 .NET 参考源 (referencesource.microsoft.com)。 UniqueID 的返回值是在访问属性时计算的。如果 NamingContainer 发生更改,则 UniqueID 的内部缓存值将被重置,以便在下次访问该属性时重新计算。 我更新了我的答案以包含一些来自 .NET 3.5 参考源的代码。【参考方案2】:我是否可以重新排列 Page_PreInit() 中的层次结构,以便当我的代码在 Page_Init() 中触发时,我将分配正确的 UniqueId?
我不能确切地知道你想要做什么,但听起来微软不鼓励这样做:
通常,您不需要使用 UniqueID 属性。例如, 你不应该写这样的代码 通过使用引用控件 生成的预测值 UniqueID 属性。你可以阅读和 传递 UniqueID 的值 其他进程的财产,但你 不应该依赖它有一个 具体结构。
【讨论】:
【参考方案3】:来自MSDN:
生成此标识符 页面请求时自动 已处理。
所以是的,您可以在 PreInit 期间访问 uniqueId
编辑
好吧,我想我有点含糊。 Page.ProcessRequest
调用 FrameworkInitialize()
方法,该方法将构建控制树。这发生在 PreInit 之前,因此控件的 UniqueId 可用。
【讨论】:
在请求过程中发生了大量的事情,我建议发帖人知道这一点,并询问在请求过程中具体是在哪里为属性赋予了价值? 您的回答就像将出生描述为“婴儿从母亲的身体里出来”。是的,它是正确的,但它是如此模糊,以至于信息没有用。以上是关于Control.UniqueId 何时创建?的主要内容,如果未能解决你的问题,请参考以下文章
uni-gram 何时比 bi-gram(或更高的 N-gram)更合适?
学习uni-app 第二步 认识uni-app/创建使用uni-app