Pregunta

Tengo un problema al utilizar LoadControl (type, Params) . Déjame explicarte ...

Tengo un control de usuario super simple (ascx)

<%@ Control Language="C#" AutoEventWireup="True" Inherits="ErrorDisplay" Codebehind="ErrorDisplay.ascx.cs" EnableViewState="false" %>

<asp:Label runat="server" ID="lblTitle" />
<asp:Label runat="server" ID="lblDescription" />

con el código (c #) detrás de:

public partial class ErrorDisplay : System.Web.UI.UserControl
{

    private Message _ErrorMessage;    

    public ErrorDisplay()
    {
    }

    public ErrorDisplay(Message ErrorMessage)
    {
        _ErrorMessage = ErrorMessage;
    }    

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);

        if (_ErrorMessage != null)
        {
            lblTitle.Text = _ErrorMessage.Message;
            lblDescription.Text = _ErrorMessage.Description;
        }
    }
}

En otra parte de mi aplicación web, estoy agregando una instancia del control de usuario a la página con el siguiente código:

divValidationIssues.Controls.Add(LoadControl(typeof(ErrorDisplay), new object[] { MessageDetails }));   

Estoy usando la versión sobrecargada de LoadControl porque quiero pasar el parámetro Mensaje al constructor. Todo esto aparece para funcionar bien.

Sin embargo, cuando se ejecuta OnPreRender () en ErrorDisplay usercontrol, las variables lblTitle y lblDescription son null , a pesar de que tienen un equivalente de marcado. La variable de mensaje se ha rellenado correctamente.

¿Puede alguien arrojar alguna luz sobre por qué esto puede estar sucediendo?

Gracias

EDIT:

Para mayor claridad, también agregaré que el código que agrega programáticamente el control de usuario a la página se está ejecutando en respuesta a una pulsación de botón, por lo que la 'página de hospedaje' ha progresado a través de Init, Page_Load y ahora está procesando el evento. manejadores.

No puedo agregar los controles de usuario en una etapa anterior del ciclo de vida del ASP, ya que se crean en respuesta a un evento de clic de botón.

¿Fue útil?

Solución

También he probado el siguiente código, que produce el mismo resultado (es decir, tanto lblTitle como lblDescription son nulos)

protected void Page_Load(object sender, EventArgs e)
{
    if (_ErrorMessage != null)
    {
        lblTitle.Text = _ErrorMessage.Message;
        lblDescription.Text = _ErrorMessage.Description;
    }
}

Tenía el entendimiento de que la función LoadControl trajo el control que está cargando hasta el 'estado' actual de la página en la que se incluye. por lo tanto, el Init, la carga de página, etc. se ejecutan como parte de la llamada a LoadControl.

Es interesante que esta publicación (sin respuesta) en los foros de asp.net muestra el mismo problema que estoy experimentando.

Publicación de foros de MSDN

Adicionalmente - Desde el MSDN:

  

Cuando carga un control en un control de contenedor, el contenedor genera todos los eventos de control agregado hasta que se ha puesto al día con el evento actual. Sin embargo, el control agregado no alcanza el procesamiento de datos de devolución de datos. Para que un control agregado participe en el procesamiento de los datos de devolución, incluida la validación, el control debe agregarse en el evento Init en lugar de en el evento Load.

Por lo tanto, ¿no debería LoadControl inicializar correctamente el control?

EDIT:

Ok, así que estoy respondiendo mi propia pregunta aquí ...

Encontré una versión respondida de la publicación del foro que vinculé anteriormente Aquí

Esencialmente, la respuesta es que el LoadControl (type, params) no puede inferir el ascx de 'página enfrente' para analizar y, por lo tanto, no se molesta en inicializar ninguno de los controles. Cuando utiliza la versión LoadControl (" ruta de acceso de ascx ") , se le da la página en frente y, por lo tanto, realiza todo el análisis y la revisión.

En resumen, necesito cambiar el código que está inicializando el control y dividirlo en partes separadas. Es decir,

Control ErrorCntrl = LoadControl("ErrorDisplay.ascx");
ErrorCntrl.ID = SomeID;
(ErrorCntrl as ErrorDisplay).SetErrorMessage = MessageDetail;
divErrorContainer.Controls.Add(ErrorCntrl);

Y debería funcionar bien ... No es tan limpio como mi intento anterior, pero al menos funcionará.

Todavía estoy abierto a sugerencias para mejorar lo anterior.

Saludos

Otros consejos

De acuerdo con Mitchel, deberías poder poner una carga de página en el código de control, que se activará una vez que los controles estén completamente disponibles.

Bueno, siempre está agregando su propio evento de carga y llamándolo después de ejecutar el constructor y agregar el control a la página, pero no es muy diferente de lo que tiene, aunque podría elegirlo por razones de estilo.

¡Me alegra que hayas encontrado una respuesta a tu problema!

Aquí es una publicación de blog escrita por Steven Robbins. La publicación explica cómo pasar parámetros para un control de usuario usando LoadControl , similar a lo que LoadControl (Type, object []) haría, a menos que funcione :)

Tuve un problema similar con el evento DayRender del control de Calendario, en el sentido de que quería agregar un control de usuario a la colección e.Cell.Controls. Después de probar un par de enfoques fallidos con el control de usuario page_load no disparar o el cuadro de lista en el Ascx arrojando una excepción nula, encontré que si inicializo mi control en el formulario con LoadControl (ascx) y luego comienzo a acceder a los controles de marcado en el Ascx, todo funcionó bien. Este enfoque no depende en absoluto del evento Page_Load en el ascx.

marca ASCX

    

código detrás

Clase pública CPCalendarCell     Hereda System.Web.UI.UserControl

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

End Sub

Public Sub Add(txt As String)
    Dim li As New ListItem(txt, txt)
    lstDay.Items.Add(li)
End Sub

Clase final

marcado ASPX de la página

     

código detrás del evento Calendar DayRender en el formulario

Private Sub Calendar1_DayRender(sender As Object, e As System.Web.UI.WebControls.DayRenderEventArgs) Handles Calendar1.DayRender
    Dim div As CPCalendarCell = LoadControl("~/UserControls/CPCalendarCell.ascx")
    div.ID = "dv_" & e.Day.Date.ToShortDateString.Replace(" ", "_")

    **e.Cell.Controls.Add(div)**

    div.Add(e.Day.Date.Month.ToString & "/" & e.Day.Date.Day.ToString)
    div.Add("Item 1")
    div.Add("Item 2")
    e.Cell.Style.Add("background-color", IIf(e.Day.IsWeekend, "whitesmoke", "white").ToString)
End Sub

Durante el ciclo de vida de la página asp.net, sus controles no se han agregado completamente en el pre-procesamiento, ¿por qué no carga los valores en page_load?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top