15 Stimmen

Asp.net Usercontrol LoadControl Problem

Ich habe ein Problem bei der Verwendung von LoadControl( type, Params ) . Lassen Sie mich erklären ...

Ich habe eine super einfache Benutzersteuerung (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" />

mit Code ( c# ) dahinter:

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;
        }
    }
}

An anderer Stelle in meiner Webanwendung füge ich mit dem folgenden Code eine Instanz des Benutzerkontrolls zur Seite hinzu:

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

Ich verwende die überladene Version von LoadControl, weil ich den Parameter Message an den Konstruktor übergeben möchte. All dies erscheint gut zu funktionieren.

Wenn jedoch die OnPreRender() auf dem ErrorDisplay-Benutzerelement ausgelöst wird, sind die Variablen lblTitle und lblDescription beide null obwohl sie ein Äquivalent für den Aufschlag haben. Die Nachrichtenvariable wurde korrekt ausgefüllt.

Kann mir jemand sagen, woran das liegen könnte?

Merci

EDIT :

Der Klarheit halber füge ich noch hinzu, dass der Code, der das Benutzerelement programmatisch zur Seite hinzufügt, als Reaktion auf einen Tastendruck ausgeführt wird, so dass die "Hosting-Seite" Init und Page_Load durchlaufen hat und nun die Event-Handler verarbeitet.

Ich kann die Benutzerkontrollen nicht in einer früheren Phase des Asp-Lebenszyklus hinzufügen, da sie als Reaktion auf ein Schaltflächenklickereignis erstellt werden.

23voto

Ash Punkte 4891

Ich habe auch den folgenden Code ausprobiert, der das gleiche Ergebnis liefert (d. h. sowohl lblTitle als auch lblDescription sind null)

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

Ich hatte das Verständnis, dass die LoadControl-Funktion das Steuerelement, das sie lädt, auf den aktuellen "Zustand" der Seite bringt, in die sie eingebunden wird. Daher werden Init, Page_Load usw. alle als Teil des LoadControl-Aufrufs ausgeführt.

Interessanterweise weist dieser (unbeantwortete) asp.net-Forumsbeitrag das gleiche Problem auf, das ich erlebe.

MSDN-Foren Beitrag

Zusätzlich - Aus dem MSDN:

Wenn Sie ein Steuerelement in ein Container-Steuerelement laden, löst der Container alle Ereignisse des hinzugefügten Steuerelements aus, bis er das aktuelle Ereignis eingeholt hat. Allerdings holt das hinzugefügte Steuerelement die Postback-Datenverarbeitung nicht ein. Damit ein hinzugefügtes Steuerelement an der Postback-Datenverarbeitung, einschließlich der Validierung, teilnehmen kann, muss das Steuerelement im Init-Ereignis und nicht im Load-Ereignis hinzugefügt werden.

Sollte LoadControl das Steuerelement daher nicht korrekt initialisieren?

EDIT :

Ok, ich beantworte hier also meine eigene Frage.

Ich habe eine beantwortete Version des Forumsbeitrags gefunden, auf den ich oben verlinkt habe Hier

Die Antwort lautet im Wesentlichen, dass die LoadControl( type, params ) kann das ascx "page infront" nicht ableiten, um es zu analysieren, und macht sich daher nicht die Mühe, eines der Steuerelemente zu initalisieren. Wenn Sie die LoadControl( "ascx path" ) Version wird die Seite vorangestellt und übernimmt somit das gesamte Parsing und die Initalisierung.

Zusammenfassend muss ich also den Code ändern, der das Steuerelement initialisiert, und ihn in einzelne Teile aufteilen. I.e.

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

Und es sollte gut funktionieren. Es ist nicht so ordentlich wie mein vorheriger Versuch, aber zumindest wird es funktionieren.

Ich bin immer noch offen für Vorschläge zur Verbesserung der oben genannten Punkte.

Prost

0voto

thismat Punkte 2096

Übereinstimmend mit Mitchel, sollten Sie in der Lage sein, eine page_load in der Steuerung Code selbst, die nach der Kontrollen vollständig verfügbar sind Feuer wäre zu setzen.

0voto

thismat Punkte 2096

Nun, es gibt immer das Hinzufügen Ihrer eigenen Load-Ereignis und rufen Sie es, nachdem Sie den Konstruktor ausgeführt haben und fügte hinzu, das Steuerelement auf der Seite, aber es ist nicht viel anders als das, was Sie haben, obwohl ich es für Stil Gründe wählen könnte.

Schön, dass Sie eine Antwort auf Ihr Problem gefunden haben!

0voto

bflemi3 Punkte 6649

Hier ist ein Blogbeitrag von Steven Robbins. Der Beitrag erklärt, wie man Parameter für ein Benutzersteuerelement mit LoadControl ähnlich dem, was LoadControl(Type, object[]) tun würde, außer es funktioniert :)

0voto

WebKing Punkte 1

Ich hatte ein ähnliches Problem mit dem Kalender-Steuerelement DayRender-Ereignis, in dem ich ein Benutzer-Steuerelement in die e.Cell.Controls-Sammlung hinzufügen wollte. Nachdem ich einige fehlgeschlagene Ansätze ausprobiert hatte, bei denen das Page_Load-Ereignis des Benutzersteuerelements nicht ausgelöst wurde oder die Listbox auf dem ascx eine Null-Exception auslöste, stellte ich fest, dass alles gut funktionierte, wenn ich mein Steuerelement auf dem Formular mit LoadControl(ascx) initialisierte und dann auf die Markup-Steuerelemente auf dem ascx zugriff. Dieser Ansatz ist überhaupt nicht vom Page_Load-Ereignis auf dem ascx abhängig.

ASCX-Auszeichnung

Code dahinter

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

Klasse beenden

Seite ASPX-Markup

Code hinter dem Ereignis Calendar DayRender im Formular

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X