4

コントロールのUniqueIdがいつ割り当てられるか誰かが知っていますか?

現在、Page_InitにUniqueIdに基づくコードがあります。ただし、一部のビジネスロジックによっては、これが発生する前に、ページのコントロール階層を再配置する必要がある場合があります。

だから、私の主な質問は、UniqueIdはいつ割り当てられるのですか?Page_PreInit()で階層を再配置して、コードがPage_Init()で起動したときに、適切なUniqueIdが割り当てられるようにすることはできますか?

4

3 に答える 3

6

この質問に答えるために、これらの各イベントのコントロールのUniqueIDプロパティの値をログに記録する小さなコードビハインドを作成しました。

  • PreInit
  • 初期化
  • InitComplete
  • プリロード
  • ロード
  • LoadComplete
  • PreRender
  • PreRenderComplete

たとえば、最後のイベントハンドラは次のようになります。

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

次に、Unloadイベントにブレークポイントを設定し、VisualStudioのイミディエイトウィンドウを使用してログに記録された値を出力しました。

_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の.NET3.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; 
}
于 2011-03-29T13:24:00.800 に答える
1

Page_PreInit()で階層を再配置して、コードがPage_Init()で起動したときに、適切なUniqueIdが割り当てられるようにすることはできますか?

あなたが何をしようとしているのか正確にはわかりませんが、Microsoftがそれを思いとどまらせているようです。

通常、UniqueIDプロパティを使用する必要はありません。たとえば、生成されたUniqueIDプロパティの予測値を使用してコントロールを参照するコードを記述しないでください。UniqueIDプロパティの値を読み取って他のプロセスに渡すことはできますが、特定の構造を持つことに依存しないでください。

于 2011-03-29T13:15:08.960 に答える
0

MSDNから:

この識別子は、ページリクエストが処理されるときに自動的に生成されます。

そうです、PreInit中にuniqueIdにアクセスできます

編集

わかりました、私は少し漠然としていたと思います。コントロールツリーを構築するメソッドをPage.ProcessRequest呼び出します。FrameworkInitialize()これはPreInitの前に発生するため、コントロールのUniqueIdが使用可能です。

于 2011-03-29T13:01:21.560 に答える