HTML-атрибут 'name', сгенерированный для дочерних элементов управления ASP.net, вместо уникального атрибута 'ID' - PullRequest
1 голос
/ 11 апреля 2009

Сгенерированный HTML-код для моего пользовательского серверного серверного элемента управления ASP.net создает атрибут имени для дочерних элементов управления вместо атрибута id. Примерно так:

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

Идентификатор самого пользовательского элемента управления, по-видимому, правильный.

Что еще более странно для меня, так это то, что ID действительно генерируется иногда (я не знаю, при каких условиях). Но FindControl() с этим идентификатором возвращает ноль на стороне сервера. 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") нет.

Как обеспечить согласованные и предсказуемые идентификаторы?

1 Ответ

3 голосов
/ 11 апреля 2009

Они последовательны.

Внутренне, элементы управления, которые являются дочерними элементами элемента управления именами (то есть GridView), имеют свои полные идентификаторы, построенные путем добавления идентификаторов их родителей, используя "$". В случае сетки это gridID $ rowID $ cellID $ mycontrolID. Это необходимо для различения нескольких экземпляров одного и того же дочернего элемента управления (т.е. mycontrolID). Почему "$", а не "_"? Я думаю, потому что многие люди уже склонны называть свои элементы управления «my_control_something», а символ «$» так же хорош, как и любой.

Итак, GridView2 $ ctl02 $ editdis $ ctl00 - это правильный идентификатор, и поэтому он используется в качестве имени для элементов управления, таких как INPUT. Когда происходит обратная отправка, фреймворк должен иметь возможность сопоставлять ключи формы с соответствующими элементами управления.

Я думаю, что путаница с идентификаторами происходит из-за того, что идентификатор, который вы используете внутри .aspx, и идентификатор, который вы видите в HTML, - это две разные вещи. Идентификаторы на стороне клиента - только это. По любой причине, когда элемент управления отображается (используя свойство ClientID), все «$» заменяются на «_». Я предполагаю, что это было сделано, чтобы сделать его дружественным к JavaScript.

Теперь об этом 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».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...