2010-03-24 9 views
9

Todos los nombres siguientes son genéricos y no los nombres reales utilizados.Los controles agregados en el diseñador son nulos durante Page_Load

Tengo un control de usuario personalizado con un panel que contiene un par de etiquetas, ambos controles .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; 
} 

En otra página, en el código subyacente, que crean una nueva instancia del control de usuario personalizado.

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

El control de usuario toma el parámetro y los intentos de establecer las etiquetas basadas fuera del objeto pasado en.

Las etiquetas que trata de asignar los valores a son, sin embargo, null.

¿Este es un problema de ciclo de vida de ASP.net que no entiendo? Mi comprensión basada en el Microsoft ASP.net lifecycle page fue que los controles de página estaban disponibles después de la Page_Initialization.

¿Cuál es la forma correcta de hacer esto? ¿Hay una mejor manera?

EDITAR: Debajo he intentado usar Page.LoadControl.

Si cargo el control basándose en la representación de cadena de la ruta y el nombre de archivo, prohíbe pasar un parámetro. Puedo eludir esto agregando un método que me permite establecer el objeto. Mientras esto funciona, se siente hackish. Preferiría poder pasar el valor al constructor si esto es posible.

El uso del método sobrecargado da el mismo resultado que cargar solo el código detrás, las etiquetas que se asignan son nulas.

EDITAR: Aparentemente, el método sobrecargado sin ejemplificar los controles secundarios agregados en el archivo .ascx es "por diseño". Encontré esto en los comentarios en Microsoft's page for Page.LoadControl(type, object[])

+0

Estás utilizando una terminología confusa. Un control personalizado y un control de usuario son cosas totalmente diferentes. Un control de usuario tiene un código ascx y un código detrás, mientras que un control personalizado es simplemente una clase que entra en la clase System.Web.UI.Control. ¿Qué estás tratando de crear y cómo los estás agregando a la página? ¿Qué estás tratando de usar? –

+0

Estoy creando un control de usuario. Actualizaré el código para reflejar eso. En cuanto a cómo se agregan, creo una instancia del control y luego lo agrego a la página a través de su colección de controles. – mwright

Respuesta

11

Cuando crea una instancia del código detrás de la clase del control de usuario, no crea una instancia del control de usuario. El control de usuario real es la clase que se crea a partir del marcado en el archivo .ascx, y esa clase hereda del código detrás de la clase.

Si desea crear controles de usuario dinámicamente, utilice el método Page.LoadControl.Se va a crear una instancia del control de usuario en el código detrás de las referencias de control corresponden a los controles creados a partir del marcado:

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

Pero eso no le da la oportunidad de enviar parámetros al constructor, lo que podría querer utilizar la sobrecarga que toma un tipo:.

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

(no estoy seguro de lo que el parámetro de tipo debe ser realmente Lógicamente debe ser del tipo de la página Ascx en lugar del tipo de la clase de código subyacente .)

+1

Aunque creo que lo que ha dicho aquí es correcto, los controles, cuando se crean usando la sobrecarga, siguen apareciendo como nulos cuando intento asignarles valores. ¿Algún otro pensamiento? – mwright

+0

@mwright: si usa el tipo del código detrás de la clase, tiene el mismo problema que cuando crea una instancia de la clase. Debe usar el tipo de la clase creada a partir del archivo de marcado. El nombre de clase del control de usuario se basa en el nombre del archivo si no hay un atributo 'ClassName' en la directiva' @ Control'. – Guffa

+0

Esto ayudó a lo grande. Gracias –

0

Puede intentar llamar a EnsureChildControls en el controlador Page_Load del control personalizado, aunque AFAIK no debería ser estrictamente necesario.

¿Cuándo/dónde agrega el control personalizado a la colección Controles?

10

Utilice la directiva Register en su m arkup de la página/control de usuario principal:

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

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

Esto solucionó el problema que tenía. Tengo un TagPrefix especificado en el archivo web.config que impedía que la página se quejara, pero no había incluido la directiva de registro en la página (y es un control en el mismo proyecto con un archivo ascx). – davidpricedev

Cuestiones relacionadas