Ich habe mich nun schon das zweite Mal von ASP.NET hereinlegen lassen und meine Zeit damit vergeudet ein und demselben
"Phänomen" auf die Spur zu kommen, daß es nun an Zeit ist einmal darüber zu schreiben. Vielleicht kann ich es mir dann
besser merken. Die Rede ist vom Einsatz von User-Controls in Repeatern.
Meine Webs basieren sehr stark auf Repeatern, weil ich zum einen die volle Kontrolle über den erzeugten Markup
behalten möchte und zum anderen, weil ich die Inline-Style-Orgien, die man verursacht, wenn man vorgefertigte Controls wie
das GridView verwendet und dabei dessen Attribute zum "Formatieren" der Ausgabe benutzt, ablehne. Styles gehören für mich
in eingebundene CSS-Dateien.
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div class="myclass">
<a href="<%#Eval("LinkUrl")%>"><%#Eval("LinkText")%></a>
</div>
</ItemTemplate>
</asp:Repeater>
Genauso wichtig ist für mich ein gerüttelt Maß an "Code-Normalisierung", d.h. immer wiederkehrende Elemente sollten in
User-Controls zusammengefasst und vereinheitlicht werden. So braucht man kleine Änderungen am Layout nicht x-Mal durchzuführen,
sondern man passt einmal das Control an und fertig. Alle Daten, die das Control benötigt, werden dabei über Properties von außen
übergeben und zum Beispiel im Markup des Control über Inline-Code in den auszugebenden Markup eingesteuert.
<%@ Control
Language="VB"
AutoEventWireup="false"
CodeFile="MyControl.ascx.vb"
Inherits="controls_MyControl" %>
<div class="myclass">
<a href="<%=Me.LinkUrl%>"><%=Me.LinkText%></a>
</div>
Beide Vorgehensweisen zusammen haben allerdings einen kleinen aber feinen Haken, wenn man den Repeater in der Hauptseite
belassen muss und mit der Methode Eval("Feldname"), der Kurzform von Eval(Container.DataItem, "Feldname"),
dem User-Control die Daten übergeben möchte. Schauen wir uns mal eine 1:1-Umsetzung der Hauptseite des Beispiels an:
<%@ Register
TagPrefix="uct"
TagName="MyControl"
Src="~/controls/MyControls.ascx" %>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<uct:MyControl LinkUrl="<%#Eval("LinkUrl")%>"
LinkText="<%#Eval("LinkText")%>"
runat="server" />
</ItemTemplate>
</asp:Repeater>
Was wird gerendert?
...
<uct:MyControl LinkUrl="http://www.yahoo.de" LinkText="Yahoo" />
<uct:MyControl LinkUrl="http://www.google.de" LinkText="Google" />
<uct:MyControl LinkUrl="http://www.live.de" LinkText="Live" />
...
Das Control wird gerendert, wie es definiert wurde! ASP.NET erachtet es nicht für nötig zu erkennen, dass wir ein
User-Control im Einsatz haben!
Der Fehler liegt im Einsatz der (doppelten) Hochkommas bei der Definition der Attribute. Was bei
einfachen HTML-Controls
(in diesem Falle das HtmlLink-Control a) noch funktioniert, schlägt bei User-Controls fehl.
Lassen wir die Hochkommas der Attribute einfach weg, beschwert sich Visual Studio, das Attribute in Hochkommas
eingeschlossen sein müssen. Des Rätsels Lösung ist der Einsatz von einfachen Hochkommas bei der
Angabe der Attribute:
<uct:MyControl LinkUrl='<%#Eval("LinkUrl")%>'
LinkText='<%#Eval("LinkText")%>'
runat="server" />
Mein Dank gilt (wieder einmal) dem sehr empfehlenswerten Forum ASP.Net Zone und dort
insbesondere dem Hinweis von Stefan Falz im Thread
Usercontrol in einem Repeater - Property übergabe.
Manchmal dauerts halt etwas länger, bis man etwas verinnerlicht hat ;)