有人知道何时分配控件的 UniqueId 吗?

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

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

最佳答案

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

  • PreInit
  • 初始化
  • 初始化完成
  • 预加载
  • 加载
  • 加载完成
  • 预渲染
  • PreRenderComplete

  • 例如,最后一个事件处理程序如下所示:
    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/

    10-11 01:07