← Journal · Archiv

HOWTO: Rekursive User Controls in ASP.net

March 05, 2007

Die Möglichkeit in ASP.net User Controls zu erstellen ist eine gigantische Erleichterung beim Programmieren großer Webanwendungen. User Control bedeutet, wiederverwendbare Klassen mit eigenem HTML-Frontend.
In meinem ggw. Hauptprojekt bei zeta software ist es nötig gewesen Datenbank-Objekte in HTML hierarchisch, und zwar mit einer unendlichen Tiefe, darzustellen.
Ziel war es eine rekursive Schleife die die Datenbank-Objekte baumartig als HTML ausgibt. Ähnlich einem Tree hatte jedes Datenbank-Objekt nur einen »Parent« also Elternteil.
Mit einem User Control lässt sich dieses Ziel sehr einfach erreichen.
Ein User Control, dass das Datenbank-Objekt repräsentiert, ruft einfach weitere Instanzen von sich selbst mit seinen “Kindern” als Inhalt auf. Da aber der Compiler kein Assembly laden kann, dass er erst noch compilieren muss, scheitert der Versuch ein User Control in selben User Control zu verwenden mit

Zirkuläre Dateiverweise sind nicht zugelassen.

Der Trick, damit’s doch klappt, ist, erst während der Laufzeit die Kind-User Controls zu erzeugen und in einen ASP-Placeholder zu packen. Ähnlich einem Repeater. Im ASP.net-Code sieht das so aus:

<asp:Label
  id="LabelName"
  runat="server" />
<br />
<asp:PlaceHolder
  id="DummyRepeater"
  runat="server" />

Im Page_Load des User Controls werden dann die Instanzen für die “Kinder” zur Laufzeit erzeugt und in den o. g. Placeholder gepackt.

protected void Page_Load(object sender, EventArgs e)
{
  // Ggw. Dummy laden anhand DummyID-Property
  DBObjects.Dummy currentDummy = DBObjects.Dummy.GetByID(DummyID);
  LabelName.Text = currentDummy.Name;

  foreach (DbObjects.Dummy dummy in CurrentDummy.Childs)
  {
    // Control hinzufügen
    Controls_Dummy newDummy =
      (Controls_Dummy)Page.LoadControl("~/Controls/Dummy.ascx");
    newDummy.DummyID = dummy.ID;
  }
}

Das User-Control bekommt dann noch ein Property (DummyID), damit es bei Page_Load auch selber weiß, welches Datanbank-Objekt mit ihm assoziert ist und daraufhin wieder den Placeholder mit Kinder-User Controls füllen kann, die wiederum ihre Kinder in ihren Placeholder packen.
Das Tolle ist, dadurch muss man sich selber nicht um die Rekursion kümmern - die Hierarchie erstellt sich von ganz alleine.

3 Kommentare

Uwe Keim ·

Sehr gut dokumentiert. Danke!

lemming ·

*stolzwieoskar*

Sven Sönnichsen ·

Wie ist der Typ Controls_Dummy definiert?
Ich habe vor dem Problem gestanden innerhalb von Usercontrols auf andere Usercontrols zuzugreifen bzw. Methoden aufzurufen. Ich bin dann den Weg über ein Interface gegangen. Ähnlich wie unter
beschrieben

Kommentar hinterlassen