Peter Bucher - Mein Experiment, meine Spielereien, meine Welt...   ·   Stefan Falz   ·   Jürgen Gutsch   ·   Golo Roden   ·   ASP.NET Zone   ·   Microsoft ASP.NET
Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

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

Veröffentlicht Sonntag, 24. Februar 2008 14:54 von Peter Bucher
Abgelegt unter: , , ,

Kommentare

# re: Ein WebControl das keine ClientID rendert

top. guter beitrag :-) dieses id zeugs nervt wirklich. und das austaschen des klassennamens ist ja wirklich einfach :-)

Sonntag, 24. Februar 2008 15:11 by jolli

# re: Ein WebControl das keine ClientID rendert

Danke für den Kommentar Johannes!

Jups, nichts ist unmöglich mit ASP.NET, das zeigs wieder :-)

Eine generische Lösung ohne eine zusätzliche Klasse gibts IMO, AFAIK leider nicht.

Aber das ist ja verträglich und schnell ausgetauscht.

Sonntag, 24. Februar 2008 16:53 by Peter Bucher
Anonyme Kommentare sind nicht zugelassen