FindControl и INamingContainer - PullRequest
       6

FindControl и INamingContainer

1 голос
/ 17 ноября 2011

Я хочу тщательно сформулировать этот вопрос, чтобы полезные люди не вмешивались и не тратили свое время на то, чтобы рассказать мне информацию, которую я уже знаю (я не хочу тратить свое время).

Я хочучтобы понять, как FindControl работает в проектах веб-приложений ASP.NET (тех, где файлы c # упоминаются как CodeBehind, а не CodeFile, в разметке).

У кода есть два файла, которые находятся между файлом разметки.Например, у Default.aspx будут Default.aspx.cs и Default.aspx.designer.cs

Если вы поместите кнопку на страницу, она будет добавлена ​​в файл конструктора.Например: protected global :: System.Web.UI.WebControls.LinkButton LinkButton1;

Если вы хотите получить ссылку на этот элемент управления, он сразу же становится доступным в качестве члена класса Default.Например, this.LinkButton1.Text = "Click Me";

Если вы посмотрите на трассировку для страницы, ей присваивается уникальный идентификатор в соответствии с поведением для INamingContainers (здесь, страницы): ctl00 $ ContentPlaceHolder1$ LinkButton1

Я не понимаю, почему оператор возвращает ноль: Control c = Page.FindControl ("LinkButton1");

Я понимаю, что это не нужно, так каккнопка уже доступна классу Default.И это потому, что он отображается как член в файле Default.aspx.designer.cs.

Я не понимаю, что такое , почему возвращается null.Поскольку страница реализует INamingContainer, а кнопка имеет идентификатор, который соответствует ожидаемому для элемента управления в INamingContainer.Разве это не то, что находит FindControl?

Ответы [ 2 ]

3 голосов
/ 17 ноября 2011

Такое поведение было для меня новым, возможно, потому, что я бы не стал искать элемент управления, который в любом случае доступен напрямую. Я думаю, что это также может быть причиной того, что ASP.NET даже не позволяет этого, потому что быстрее и безопаснее использовать существующую ссылку, чем находить ее (или нет).

Метод FindControl можно использовать для доступа к элементу управления, идентификатор которого не является доступны во время разработки. Метод ищет только страницы контейнер непосредственного или верхнего уровня; он не ищет рекурсивно элементы управления в контейнерах именования, содержащихся на странице. Чтобы получить доступ элементы управления в подчиненном контейнере именования, вызовите FindControl метод этого контейнера.

http://msdn.microsoft.com/en-us/library/31hxzsdw.aspx

Редактировать : После того, как я проверил это поведение, я заметил, что null возвращается только при использовании на странице с MasterPage, поскольку единственным элементом управления в ControlCollection страницы является сам MasterPage , В этом есть смысл. Вы не можете гарантировать, что идентификатор будет уникальным, когда элемент управления находится на верхнем уровне страницы с MasterPage, поскольку другие ContentPages могут также иметь элемент управления с этим идентификатором, и FindControl может сегодня вернуть другой элемент управления, чем завтра.

Если вы посмотрите на NamingContainer элемента управления, который вы хотите найти, то увидите, что в случае MasterPage это ContentPlaceHolder, а в случае «нормальной» страницы - это сама страница.

Таким образом, вам необходимо сначала получить ссылку на ContentPlaceholder в MasterPage, прежде чем вы сможете найти элемент управления через FindControl:

Page.Master.FindControl("ContentPlaceHolder1").FindControl("LinkButton1");

http://msdn.microsoft.com/en-us/library/xxwa0ff0.aspx

3 голосов
/ 17 ноября 2011

FindControl не является рекурсивным, и похоже, что у вас есть промежуточный элемент управления ContentPlaceHolder1, который является контейнером именования, поэтому это должно работать: Page.FindControl("ContentPlaceHolder1").FindControl("LinkButton1")

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