2010-03-24 3 views
9

Все имена ниже являются общими, а не используются фактические имена.Элементы управления, добавленные в конструкторе, равны нулю во время Page_Load

У меня есть пользовательский UserControl с панелью, содержащей пару ярлыков, оба .aspx-элемента управления.

.aspx:

<asp:Panel runat="server"> 
    <asp:Label ID="label1" runat="server"> 
    </asp:Label> 
</asp:Panel> 
<asp:Panel runat="server"> 
    <asp:Label ID="label2" runat="server"> 
    </asp:Label> 
</asp:Panel> 

CodeBehind:

private readonly Object object; 
protected void Page_Load(object sender, EventArgs e) 
{ 
    // These are the lines that are failing 
    // label1 and label2 are null 
    label1.Text = object.Value1; 
    label2.Text = object.Value2; 
} 
public ObjectRow(Object objectToDisplay) 
{ 
    object = objectToDisplay; 
} 

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

protected void Page_Load(object sender, EventArgs e) 
{ 
    Usercontrol control = new UserControl(object); 
    Controls.Add(control); 
} 

пользовательский элемент управления принимает параметр и пытается установить метки на основе от объекта передается в.

Этикетки, которые он пытается присвоить значения, однако, нуль.

Является ли это проблемой жизненного цикла ASP.net, которую я не понимаю? Мое понимание, основанное на Microsoft ASP.net lifecycle page, состояло в том, что элементы страницы были доступны после Page_Initialization.

Каков правильный способ сделать это? Есть ли способ лучше?

EDIT: снизу я попытался использовать Page.LoadControl.

Если я загружаю элемент управления, основанный на строковом представлении пути и имени файла, он запрещает передачу параметра. Я могу обойти это, добавив метод, который позволяет мне установить объект. Хотя это работает, он чувствует себя взломанным. Я предпочел бы иметь возможность передать значение конструктору, если это возможно.

Использование перегруженного метода дает тот же результат, что и загрузка только кода позади, присваиваемые метки являются нулевыми.

EDIT: По-видимому, перегруженный метод, не создающий элементы управления дочерним элементом, добавленный в файл .ascx, является «по дизайну». Я нашел это в комментариях на Microsoft's page for Page.LoadControl(type, object[])

+0

Вы используете путаную терминологию. Пользовательский элемент управления и пользовательский контроль - это совершенно разные вещи. Пользовательский элемент управления имеет ascx и код позади, тогда как пользовательский элемент управления - это просто класс, который принадлежит классу System.Web.UI.Control. Что вы пытаетесь создать и как вы добавляете их на страницу. Которые вы пытаетесь использовать. –

+0

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

ответ

11

Когда вы создаете экземпляр кода, лежащего за классом пользовательского элемента управления, вы не создаете экземпляр пользовательского элемента управления. Фактический пользовательский элемент управления - это класс, созданный из разметки в файле .ascx, и этот класс наследуется от кода за классом.

Если вы хотите динамически создавать пользовательские элементы управления, вы используете метод Page.LoadControl.Это создаст экземпляр пользовательского элемента управления, где код позади ссылок управлений соответствуют элементам управления, созданным с разметки:

CustomControl control = (CustomControl)Page.LoadControl("controls/CustomControl.ascx"); 

Но это не дает вам возможность отправить параметры в конструктор, так что вы можете использовать перегрузку, которая принимает вид:.

CustomControl control = (CustomControl)Page.LoadControl(typeof(CustomControl), new object[] { objectToDisplay }); 

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

+1

Хотя я считаю, что то, что вы сказали здесь, является правильным, элементы управления, когда они создаются с использованием перегрузки, все еще появляются как null, когда я пытаюсь присвоить им значения. Любые другие мысли? – mwright

+0

@mwright: Если вы используете тип кода за классом, у вас такая же проблема, как при создании экземпляра класса. Вы должны использовать тип класса, созданного из файла разметки. Имя класса элемента управления пользователя основано на имени файла, если в директиве '@ Control' нет атрибута' ClassName'. – Guffa

+0

Это очень помогло. Спасибо –

0

Вы можете попробовать вызвать EnsureChildControls в обработчике Page_Load пользовательского элемента управления, хотя AFAIK это не должно быть строго необходимо.

Когда вы добавляете пользовательский элемент управления в коллекцию Controls?

10

Используйте директиву Register в вашем м arkup страницы/родительский пользовательский контроль:

<%@ Register TagPrefix="wb" src="~/CustomControl.ascx" TagName="CustomControl" %> 

<asp:CustomControl runat="server" /> 
+0

Это исправило проблему. У меня есть tagPrefix, указанный в файле web.config, который заставлял страницу жаловаться, но я не включил директиву регистров на странице (и это элемент управления в том же проекте с ascx-файлом). – davidpricedev

Смежные вопросы