Ein WebControl das keine ClientID rendert
Jedes Control das von der Klasse WebControl erbt, rendert automatisch ClientIDs in einem ID Attribut.
Dieses Rendering geschieht in der Methode AddAttributesToRender der Basisklasse WebControl.
Was nun tun, wenn keine ClientIDs in der Ausgabe erwünscht sind?
1. Die Eigenschaft ClientID überschreiben und null / String.Empty zurückgeben
2. Die Methode AddAttributesToRender übschreiben und dort Logik einbauen
Nummer 1. hat den Nachteil, dass das Attribut "id" immer noch gerendert wird, einfach mit keinem Inhalt -> fällt eher weg.
Nummer 2 ist genau das gesuchte, laut der Implementierung von WebControl wird das Attribut und dessen Wert weggelassen wenn die Eigenschaft ID null zurückgibt.
Resultat (Für ein HyperLink ohne ClientID Ausgabe):
/// <summary>
/// Ein HyperLink Control, das keine ClientIDs rendert
/// </summary>
public class HyperLinkClientIdLess : HyperLink {
protected override void AddAttributesToRender(HtmlTextWriter writer) {
string id = this.ID;
this.ID = null;
base.AddAttributesToRender(writer);
this.ID = id;
}
}
Wieso klappt das?
In der Methode der Basisklasse ist die Logik, die wir auch immer noch benötigen.
Diese Logik bringt uns das benötigte Verhalten, wenn ID == null ist.
Natürlich brauchen wir die ID später immer noch, deshalb wird sie einfach temporär (Für den Aufruf der Basismethode) auf null gesetzt.
Sinn / Unsinn?
Ich brauche das bspw. für ein Menu Control. Dort benötige ich keinen clientseitigen Zugriff auf die gerenderten Anker,
somit wären diese überflüssig.
Zudem lässt sich dieses Verhalten rein durch Austauschen des Klassennamens wieder rückgängig machen.
*Update
Ganz wichtig ist natürlich, das ein solches Unterfangen jeglichem Control, das Daten zurück an den Server senden
sollte / muss, diese Möglichkeit nimmt.
Ein Calendar Control, eine TextBox wird damit nicht mehr funktionieren bzw. nicht mehr über den normalen Mechanismus von ASP.NET.
Neue Möglichkeit
Aha, ich habe mich geirrt. Es gibt eine generische Lösung.
Bei meiner Lösung habe ich darauf geachtet, das die ID wiederhergestellt wird, jedoch wird diese sowieso nicht mehr benötigt.
Folgende Idee: http://www.vikramlakhotia.com/Removing_ID_of_controls_to_reduce_HTML_Size.aspx
D.h. man hängt sich in den PreRender Event irgend eines Control, Typ: "Control" ein, und setzt die ID auf null.
Bspw. so:
protected void Page_Load(object sender, EventArgs e) {
this.<Control>.PreRender += this.DeleteId;
}
protected void DeleteId(object sender, EventArgs e) {
(sender as Control).ID = null;
}
IDs aller Labels auf der Seite entfernen
Und da diese Lösung nur auf den Typ Control angewiesen und deswegen generisch ist,
ergibt sich bspw. die Möglichkeit die ID aller Labels automatisch zu entziehen:
ControlCollection controls = <Alle Controls der Seite (Rekursiver Aufruf)>;
foreach(Control c in controls) {
if(c is Label) {
c.PreRender += this.DeleteId;
}
}