Pergunta

Estou tendo um problema ao usar LoadControl( type, Params ). Deixe-me explicar ...

Eu tenho um controle simples super utilizador (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" />

com código (c #) por trá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;
        }
    }
}

Em outro lugar na minha aplicação web que eu estou adicionando uma instância do UserControl para a página usando o seguinte código:

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

Eu estou usando a versão sobrecarregada do LoadControl porque eu quero passar o parâmetro Mensagem para o construtor. Tudo isto aparece para ok trabalho.

No entanto, quando o OnPreRender() é disparado no ErrorDisplay usercontrol as variáveis ??lblTitle e lblDescription são ambos null, apesar de eles terem uma marcação equivalente. A variável mensagem foi corretamente preenchidos.

Alguém pode lançar alguma luz sobre por que isso pode estar acontecendo?

Graças

EDIT:

Apenas para maior clareza eu vou acrescentar também que o código que é programaticamente adicionar o usercontrol para a página está sendo executado em resposta ao pressionar um botão, então a 'página que hospeda' progrediu através Init, Page_Load e agora está processando o evento manipuladores.

Eu não posso adicionar os usercontrols numa fase mais precoce do ciclo de vida asp como eles estão sendo criados em resposta a um evento de clique de botão.

Foi útil?

Solução

Eu tentei o código a seguir, bem como - que produz o mesmo resultado (ou seja, tanto lblTitle e lblDescription são nulos)

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

Eu tive o entendimento de que a função LoadControl trouxe o controle que está sendo carregado até o 'estado' atual da página na qual ele está sendo incluído no. daí o Init, Page_Load etc são todos executados como parte da chamada LoadControl.

Curiosamente este (sem resposta) asp.net fóruns postar exposições o mesmo problema que eu estou experimentando.

MSDN Publicar

Além disso - A partir da MSDN:

Quando você carregar um controle em um controle de recipiente, o recipiente levanta todos os eventos do controle adicionado até que ele foi pego ao evento atual. No entanto, o controlo não se adicionou apanhar com o processamento de dados nova colocação. Para um controle adicional para participar no processamento de dados postagem, incluindo a validação, o controle deve ser adicionado no evento de inicialização em vez de no evento Load.

Por isso não deve LoadControl corretamente initalise o controle?

EDIT:

Ok, então eu estou respondendo a minha própria pergunta aqui ..

Eu encontrei uma versão respondeu do post no fórum que eu link acima Aqui

Essencialmente, a resposta é que o LoadControl( type, params ) não se pode inferir o ascx A página de frente "para análise e, portanto, não incomoda initalising qualquer um dos controles. Quando você usa a versão LoadControl( "ascx path" ) é dado a frente página e, portanto, faz toda a análise e initalision.

Então, em resumo eu preciso alterar o código que está initalising o controle e dividi-lo em partes separadas. I.

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

E ele deve funcionar ok .. Não é tão limpo como a minha tentativa anterior, mas pelo menos ele vai trabalhar.

Eu ainda estou aberto a sugestões para melhorar o acima.

Felicidades

Outras dicas

Concordando com Mitchel, você deve ser capaz de colocar um page_load no próprio código de controle que seria acionado após os controles são completamente disponíveis.

Bem, há sempre adicionando seu próprio evento de carga e chamá-lo depois de ter corrido o construtor e acrescentou o controle para a página, mas não é um diferente muito do que você tem, embora eu possa escolhê-lo por razões de estilo.

Que bom que você encontrou uma resposta para o seu problema!

Aqui é um post escrito por Steven Robbins. O post explica como passar parâmetros para um controle de usuário usando LoadControl, semelhante ao que LoadControl(Type, object[]) faria, exceto que funciona :)

Eu tive um problema semelhante com o evento DayRender controle de calendário, em que eu queria adicionar um controle de usuário à coleção e.Cell.Controls. Depois de tentar um par de abordagens falhou com o page_load controle do usuário não disparar ou a caixa de listagem no ascx jogando uma exceção nula, descobri que se eu inicializado meu controle no formulário com LoadControl (ascx) e, em seguida, começar a acessar os controles de marcação no ascx, tudo funcionou bem. Esta abordagem não depende do evento Page_Load no ascx em tudo.

ASCX marcação

atrás de código

CPCalendarCell Public Class Inherits 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

End Class

página ASPX marcação

código por trás de eventos Calendário DayRender no formulário

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

Por página asp.net ciclo de vida de seus controles não são totalmente adicionado na pré-render, por que você não apenas carregar os valores em page_load?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top