Question

Je rencontre un problème d'utilisation de LoadControl (type, Params) . Laissez-moi vous expliquer ...

J'ai un contrôle utilisateur très 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" />

avec le code (c #) derrière 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;
        }
    }
}

Ailleurs dans mon application Web, j'ajoute une instance du contrôle utilisateur à la page à l'aide du code suivant:

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

J'utilise la version surchargée de LoadControl car je souhaite transmettre le paramètre Message au constructeur. Tout cela semble fonctionner correctement.

Cependant, lorsque le OnPreRender () est déclenché sur le contrôle d'erreur ErrorDisplay, les variables lblTitle et lblDescription sont toutes deux null , bien qu'elles aient un équivalent de balisage. La variable de message a été correctement renseignée.

Quelqu'un peut-il expliquer pourquoi cela se produit?

Merci

EDIT:

Par souci de clarté, j'ajouterai également que le code qui ajoute par programme le contrôle utilisateur à la page est exécuté en réponse à une pression sur un bouton. La "page d'hébergement" a donc progressé dans Init, Page_Load et traite maintenant l'événement. manipulateurs.

Je ne peux pas ajouter les contrôles utilisateur à une étape précédente du cycle de vie de l'ASP, car ils sont créés en réponse à un clic sur un bouton.

Était-ce utile?

La solution

J'ai également essayé le code suivant - qui donne le même résultat (c'est-à-dire que lblTitle et lblDescription sont nuls)

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

J'avais compris que la fonction LoadControl avait amené le contrôle en cours de chargement à l'état actuel de la page sur laquelle il est inclus. Par conséquent, Init, Page_Load, etc. sont tous exécutés dans le cadre de l'appel LoadControl.

Fait intéressant, cet article de forum asp.net (sans réponse) présente le même problème que moi.

Message sur les forums MSDN

En outre, à partir du MSDN:

  

Lorsque vous chargez un contrôle dans un contrôle de conteneur, le conteneur déclenche tous les événements du contrôle ajouté jusqu'à ce qu'il ait rattrapé l'événement en cours. Toutefois, le contrôle ajouté ne rattrape pas le traitement des données de publication. Pour qu'un contrôle supplémentaire puisse participer au traitement des données de publication, y compris la validation, il doit être ajouté à l'événement Init plutôt qu'à l'événement Load.

Par conséquent, LoadControl ne doit-il pas initialiser correctement le contrôle?

EDIT:

Ok, alors je réponds à ma propre question ici ..

J'ai trouvé une version répondue du message sur le forum que j'ai lié à ce qui précède ici

La réponse est essentiellement que le LoadControl (type, params) ne peut pas déduire l'ascx 'page infront' à analyser et qu'il ne s'ennuie donc pas d'initialiser les contrôles. Lorsque vous utilisez la version LoadControl ("ascx path") , la page se trouve en face et effectue donc toutes les analyses et initalision.

Donc, en résumé, je dois changer le code qui initie le contrôle et le scinder en plusieurs parties. I.e.

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

Et cela devrait fonctionner correctement. Ce n'est pas aussi net que ma précédente tentative, mais au moins cela fonctionnera.

Je suis toujours ouvert aux suggestions visant à améliorer ce qui précède.

A bientôt

Autres conseils

En accord avec Mitchel, vous devriez pouvoir insérer un code page_load dans le code du contrôle lui-même, qui se déclencherait une fois que les contrôles seraient complètement disponibles.

Il ajoute toujours votre propre événement de chargement et l'appelle une fois que vous avez exécuté le constructeur et ajouté le contrôle à la page, mais ce n'est pas très différent de ce que vous avez, bien que je puisse le choisir pour des raisons de style. / p>

Je suis content que vous ayez trouvé une réponse à votre problème!

Voici un article de blog écrit par Steven Robbins. Cet article explique comment passer des paramètres pour un contrôle utilisateur à l'aide de LoadControl , comme ce que LoadControl (Type, objet []) ferait, sauf que cela fonctionne :)

J'ai eu un problème similaire avec l'événement DayRender du contrôle du calendrier, en ce sens que je voulais ajouter un contrôle utilisateur à la collection e.Cell.Controls. Après avoir essayé plusieurs approches infructueuses avec le contrôle utilisateur page_load ne se déclenchant pas ou la zone de liste sur l'ascx levant une exception null, j'ai constaté que si j'initialisais mon contrôle sur le formulaire avec LoadControl (ascx), puis commençais à accéder aux contrôles de balisage du ascx, tout a bien fonctionné. Cette approche ne dépend absolument pas de l'événement Page_Load sur l'ascx.

Balisage ASCX

    

code derrière

Classe publique CPCalendarCell     Hérite de 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

Classe de fin

balisage de page ASPX

     

code derrière l'événement Calendar DayRender du formulaire

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

Selon le cycle de vie de la page asp.net, vos contrôles ne sont pas entièrement ajoutés à la pré-rendu, pourquoi ne chargez-vous pas simplement les valeurs dans page_load?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top