Невозможность динамического добавления элементов управления на страницу

Я добавляю пользовательский элемент управления для каждой записи, загружаемой в считывателе данных, вот основной цикл:

while (dr.Read())
{
     ImageSelect imgSel = new ImageSelect(dr["Name"].ToString());
     myPanel.Controls.Add(imgSel);
}

Проблема в том, что на страницу не добавлены элементы управления, я проверяю вывод html, и есть моя панель, в которой ничего нет.

Я даже прошел через код в отладчике и убедился, что myPanel.Controls получает элемент управления, добавленный в каждый цикл, со счетчиком 6, без ошибок, но тогда они не отображаются на странице.

Я запустил приведенный выше код в событиях Page_Init и Page_Load, оба с тем же результатом.

РЕДАКТИРОВАТЬ: Итак, я переключился на использование LoadControl (".... ascx") для получения экземпляра элемента управления, который теперь работает. Но изначально я также передавал данные через конструктор элементов управления. Это все еще возможно или мне просто нужно установить их через get / sets?

РЕДАКТИРОВАТЬ 2: Спасибо Фредди за указание на то, что LoadControl имеет перегрузку, в которой вы МОЖЕТЕ передать параметры конструктора, см. принятый ответ.

РЕДАКТИРОВАТЬ 3: после попытки использовать этот метод как с конструктором, так и без него. Я обнаружил, что лучше просто использовать сеттеры для любых свойств, которые должен иметь элемент управления, а не пытаться использовать переданный массив объектов для моего конструктора.


person Neil N    schedule 02.04.2009    source источник
comment
@Neil возможно, выложил обновление к моему ответу.   -  person eglasius    schedule 02.04.2009
comment
Имейте в виду, что эта перегрузка не работает так же, как другая, поэтому вы можете получить исключения нулевой ссылки, если у вас есть элементы дизайнера. В моем блоге есть метод расширения, который можно обойти, если это необходимо.   -  person Steven Robbins    schedule 02.04.2009
comment
Опробовав переданные параметры, я решил, что совет Фредди по использованию сеттеров - лучший способ.   -  person Neil N    schedule 02.04.2009


Ответы (2)


Обновление: как указал Стив, перегрузка LoadControl, использующая этот тип, не будет учитывать элементы управления в ascx. Это также упоминается в этом ответе: Динамическая загрузка UserControl с методом LoadControl (Type, object []).

Как я упоминал ранее, get / set больше соответствуют модели asp.net, поэтому я рекомендую использовать это с вариантом LoadControl, который получает путь управления пользователем. Тем не менее, версия Стива - интересная альтернатива: http://www.grumpydev.com/2009/01/05/passing-parameters-using-loadcontrol/.

Я считаю, что LoadControl с типом предназначен для использования с пользовательскими веб-элементами управления.


Если это пользовательский элемент управления, вы должны использовать LoadControl (usercontrolpath) для получения экземпляра пользовательского элемента управления.

Вы можете использовать конструктор, выполнив:

var name = dr["Name"].ToString();
var imgSel = LoadControl(typeof(ImageSelect), new object[]{ name });
myPanel.Controls.Add(imgSel);

Обратите внимание, что в зависимости от модели проекта, которую вы используете, вам необходимо добавить ссылку на aspx, чтобы использовать его с вариацией typeof:

<%@ Reference Control="~/somepath/myusercontrol.ascx" %>

Пс. Я обычно использую set / get для элементов управления, так как считаю их более соответствующими модели asp.net.

person eglasius    schedule 02.04.2009
comment
Вы можете подробнее рассказать об этом? .Загрузка чего? Страница? - person Neil N; 02.04.2009
comment
@Neil y, обновил его, сбой памяти, это LoadControl, и вы указываете путь к пользовательскому элементу управления, например: ~ / somepath / mycontrol.ascx - person eglasius; 02.04.2009
comment
хорошо, понятно, теперь можно использовать параметры конструктора LoadControl, как в моем исходном примере? - person Neil N; 02.04.2009
comment
хорошо, отлично, пропустил эту перегрузку LoadControl в intellisense. Спасибо за объяснения. - person Neil N; 02.04.2009
comment
Имейте в виду, что эта перегрузка не работает так же, как другая, поэтому вы можете получить исключения нулевой ссылки, если у вас есть элементы дизайнера. В моем блоге есть метод расширения, который можно обойти, если это необходимо. - person Steven Robbins; 02.04.2009
comment
Не беспокойтесь, как вы сказали, другая перегрузка больше предназначена для настраиваемых WebControls, поэтому их немного сбивает с толку, когда они оба имеют одно и то же имя. - person Steven Robbins; 02.04.2009

Чтобы добавить UserControls, вы должны вызвать метод LoadControl, передав путь к файлу .ascx. Вы не можете создать их, просто создав экземпляр объекта, от которого наследуется файл .ascx.

UserControl состоит как из разметки, так и из класса в коде. Разметка содержит ссылку на класс позади, но класс позади не знает, где находится разметка, и поэтому не может быть создан сам по себе.

person Daniel    schedule 02.04.2009