1

カスタムASP.netサーバーコントロール用に生成されたHTMLコードは、id属性ではなく、子コントロールのname属性を生成します。このようなもの :

<span id="GridView2_ctl02_editdis">
    <input type="text" name="GridView2$ctl02$editdis$ctl00"/>
</span>

カスタムコントロール自体のIDは明らかに適切です。

私にとってさらに奇妙なのは、IDが時々生成されることです(どのような条件であるかはわかりません)。ただし、FindControl()そのIDを持つaは、サーバー側でnullを返します。FindControl()name属性の値を使用すると、問題なく機能します。

このようなもの :

<span class="TextBox" id="GridView2_ctl02_editdis">
    <input type="text" id="GridView2_ctl02_editdis_ctl00" name="GridView2$ctl02$editdis$ctl00"/>
</span>

上記の場合、FindControl("GridView2$ctl02$editdis$ctl00")正常に動作しますが、FindControl("GridView2_ctl02_editdis_ctl00")動作しません。

一貫性のある予測可能なIDを確保するにはどうすればよいですか?

4

1 に答える 1

3

それらは一貫しています。

内部的には、ネーミングコントロール(つまりGridView)の子であるコントロールは、「$」を使用して親のIDを追加することによって完全なIDを構築します。グリッドの場合は、gridID $ rowID $ cellID$mycontrolIDです。これは、同じ子コントロール(つまり、mycontrolID)の複数のインスタンスを区別するために必要です。なぜ「_」ではなく「$」なのですか?多くの人がすでにコントロールに「my_control_something」という名前を付ける傾向があり、「$」記号は他のどの記号よりも優れているためだと思います。

したがって、GridView2 $ ctl02 $ editdis $ ctl00は正しいIDであり、それがINPUTなどのコントロールの名前として使用される理由です。ポストバックが発生した場合、フレームワークはフォームキーを適切なコントロールと照合できる必要があります。

IDとの混同は、.aspx内で使用しているIDとHTMLに表示されているIDが2つの異なるものであるという事実に起因していると思います。クライアント側のIDはまさにそれです。何らかの理由で、(ClientIDプロパティを使用して)コントロールがレンダリングされると、すべての「$」が「_」に置き換えられます。私の推測では、これはjavascript/cssに対応するために行われたと思います。

さて、そのFindControl( "GridView2 $ ctl02 $ editdis $ ctl00")について...あなたは本当に可能な限りそれを避けようとするべきです。FindControlは再帰関数であり、「GridView2 $ ctl02 $ editdis$ctl00」を「GridView2」と「ctl02$editdis $ ctl00」に分割し、GridView2を検索して、子コントロールとして「ctl02 $ editdis$ctl00」があるかどうかを確認します。このプロセスは、$で区切られた各部分に対して繰り返されます。

ちなみに、深く埋もれたコントロールのためにPage.FindControlを呼び出すときはいつでも、パターンを調べて理由を尋ねる必要があります。たとえば、「GridView2 $ ctl02 $ editdis $ ctl00」で実行する必要があるものはすべて、「GridView2 $ ctl02 $ editdis$ctl01」でも実行する必要があります。その場合、おそらくOnItemCreatedまたはOnItemDataBoundで処理する必要があります。ここでは、「ctl00」について「知っている」行にアクセスできます。

于 2009-04-11T16:57:19.147 に答える