Server Controls müssen in eine Form verpackt werden

Werbung
.NET Server Controls verwenden
Die Server-seitigen Controls von .NET erlauben die Gestaltung von Webseiten, ohne Rücksicht auf
jeden einzelnen Browser nehmen zu müssen. Wie Sie die Controls richtig einsetzen, zeigt dieser
Artikel.
VON THOMAS WÖLFER
Webseiten zu bauen, ist gar nicht so einfach: Will man irgendetwas außerhalb der Reihe realisieren,
bekommt man schnell Probleme mit den unterschiedlichen Browsern. Nun hat der Internet Explorer
sich zwar im Großen und Ganzen durchgesetzt, trotzdem will man aber Netscape, Mozilla, Konqueror
oder Opera nicht aussperren. Eine einfache Lösung zur Vermeidung von Mehrarbeit bieten dabei die
.NET Server Controls.
Ein typisches Problem auf Webseiten ist die Organisation und Darstellung von hierarchischen Daten.
Optimal wäre dazu eine Baumstruktur wie im Explorer von Windows, doch das ist mit reinem HTML
eine Qual. Verwendet man hingegen Javascript, DHTML und das DOM, läuft man schnell gegen eine
Wand:
Trotz der vielfach gepriesenen Konformität zum Standard vieler Browser funktionieren die Dinge nicht
immer so, wie man sich das wünschen würde. Schlimmer noch: Mit jedem neuen Release oder Patch
verändert sich das Verhalten der Browser ein bisschen – und mit etwas Pech funktioniert dann der
eigene Code nicht mehr. Als Resultat hat man dann hinterher eine Browser-Weiche im JavascriptCode und jede Menge unterschiedlicher Implementierungen für ein und dieselbe Funktionalität. Das
gilt nicht nur für Bäume: Auch Navigationselemente wie Pulldown-Menüs und Ähnliches sind von
diesem Problem betroffen.
Dem kann mit .NET Abhilfe geschaffen werden. Dazu benötigt man einen Internet Information Server
5 oder 6 – die 5er Variante gibt es zum Beispiel in Windows 2000 und Windows XP Professional, die
6er Variante in Windows Server 2003. Zusätzlich benötigt man das .NET Framework auf dem Server.
Bei Windows 2000 und Windows XP muss man das Framework nachträglich installieren, wenn das
nicht bereits im Rahmen eines Service Packs geschehen ist. Beim Windows 2003 Server ist das
Framework von vornherein dabei.
Ob man dabei das Framework in Version 1.0 oder in Version 1.1 benutzt, ist gleichgültig, denn die
Server Controls lassen sich mit beiden Varianten verwenden.
Bäume darstellen mit dem TreeControl
TreeControls – egal ob für Client- oder Server-Seite – sind in kommerzieller Form von Drittanbietern
schon länger zu haben. Ein besonderer Fall ist da zum Beispiel der Javascript-Baum von Ansgar
Federhen, der kostenlos zu haben ist. Das Control läuft auf dem Client in Javascript und funktioniert
mit praktisch allen gängigen Browsern. Allerdings muss dazu immer eine Menge Javascript-Code
ausgeliefert werden: Wen das nicht stört, der ist mit "js-menue" gut bedient.
Praktischer sind allerdings die DHTML-Behaviours von Microsoft. Diese – nicht offiziell unterstützten –
Controls funktionieren ebenfalls rein Client-seitig, haben aber den Vorteil, dass die Bestückung mit
Daten über XML-Dateien erfolgt. Diese sind relativ einfach zu erstellen und zu warten. Der Nachteil:
Diese Elemente funktionieren ausschließlich mit dem Internet Explorer und können daher bestenfalls
in Intranets oder anderen kontrollierten Umgebungen verwendet werden.
Beim "TreeView Server Control" von .NET sieht die Sache besser aus. Es lässt sich einfach auf einer
ASP-Seite verwenden, ohne dass man sich Gedanken über den Browser des Besuchers machen
muss: Im Wesentlichen läuft die Sache dabei so ab, dass bereits beim Request des Client ermittelt
wird, welchen Code er benötigt. Je nach Client wird dann unterschiedlicher Code ausgeliefert. Im
besten Fall gibt es reines DHTML mit Script-Elementen. Bei älteren Browsern wird bei Bedarf auch
reines HTML 3.2 ausgegeben, wodurch allerdings deutlich mehr Traffic entsteht: Öffnet der Benutzer
einen Ast im Baum, so erzeugt das eine erneute Anfrage an den Server, der mit einer neuen HTMLSeite antwortet, in der der gewünschte Ast dann eben in geöffneter Form dargestellt ist.
Ähnlich wie beim DHTML-Behaviour erfolgt die Bestückung mit Daten auch beim "TreeView Server
Control" per XML-Datei. Dabei können auf Wunsch auch mehrere Dateien zum Zuge kommen. Jede
dieser Dateien wird XML-Island genannt und kann einen Teil des anzuzeigenden Baums enthalten.
Das ist dann sehr praktisch, wenn zum Beispiel unterschiedliche Teile des Baumes von
unterschiedlichen Personen verwaltet werden oder wenn ein Teil des Baumes in statischer Form
vorliegt, während ein anderer dynamisch erzeugt werden muss.
Knoten definieren: Inline oder per XML
Im Prinzip funktioniert das Ganze so, dass man für jeden Knoten im Baum eine Quelle angeben kann.
Diese Quelle ist entweder inline definiert oder sie ist ein anderes XML-Island. Zusätzlich zu seinen
Daten kann jeder Knoten eine ganze Reihe an Optionen haben. Dazu gehören beispielsweise der
anzuzeigende Text, die dazugehörige URL und auch die beiden Icons für geöffneten oder
geschlossenen Zustand der Zweige. Bei inline definierten Knoten werden diese Attribute direkt in der
Knotendefinition angegeben, bei Daten aus einem anderen XML-Island befinden sich die Attribute
innerhalb dieses Island.
Für jeden Browser: Mit dem TreeControl stellen Sie Bäume Browser-unabhängig dar.
Um das Server-basierte TreeControl benutzen zu können, muss man auf dem Webserver zwei
Verzeichnisse anlegen: bin und webctrl_client\1.0. In das Verzeichnis bin kopieren Sie einfach die DLL
mit den Controls aus dem .NET-Framework (Microsoft.Web.UI.WebControls.dll). Nach
webctrl_client\1.0 kommen die Bilder und Behaviours. Beide Elemente sind im Download zu den
WebControls auf dem Server von Microsoft zu finden. Für die WebControls gibt es übrigens auch den
Quellcode: Wenn Sie also Änderungen daran vornehmen wollen, benötigen Sie dazu das .NET
Framework SDK.
Den Download der Server Controls finden Sie hier.
Erster Test des TreeControl
Haben Sie die Support-Dateien für die Server-Controls installiert, können Sie den ersten Test mit dem
TreeControl starten. Dazu brauchen Sie eine ASPX-Seite auf Ihrem Webserver. Die Seite hat im
Wesentlichen den folgenden Inhalt:
> <%@ Register TagPrefix="ie" Namespace="Microsoft.Web.UI.WebControls"
Assembly="Microsoft.Web.UI.WebControls" %>
>
> <HTML><body>
>
> <form runat="server">
> <ie:TreeView runat="server" SystemImagesPath="/webctrl_client/1_0/treeimages"
id="TreeView1">
>
> <ie:TreeNode TreeNodeSrc="island.xml" Expanded="true"
ImageUrl="/webctrl_client/1_0/images/root.gif" Text="Ein Island"></ie:TreeNode>
>
> <ie:TreeNode IMAGEURL="../common/images/text.gif" TEXT="text1"
NAVIGATEURL="seite1.html" />
> <ie:TreeNode IMAGEURL="../common/images/text.gif" TEXT="text1"
NAVIGATEURL="seite2.html" />
>
> </ie:TreeView>
> </form>
>
> </body></HTML>
>
Ganz oben auf der Seite befindet sich eine Angabe darüber, welcher Namespace beziehungsweise
welche Assembly verwendet werden soll. Für den Namespace wird bei der Gelegenheit direkt eine
Abkürzung registriert, so dass die Objekte aus diesem Namespace später leichter verwendbar sind.
Das erledigt die Zeile Register.
Dann kommt der ganz normale HTML-Teil, bestehend aus dem HTML- und dem body-Tag.
Server Controls müssen in eine Form verpackt werden
Im Folgenden benötigen Sie ein Form. Immer wenn Sie eines der WebControls verwenden möchten,
müssen Sie das in einem Form tun – ansonsten versagen die Controls teilweise ihren Dienst. Das
Form erhält einen zusätzlichen Parameter runat, mit dem klargestellt wird, dass die Ausführung auf
dem Server stattfinden soll. Das Form wird weiter unten ebenso normal abgeschlossen, wie auch die
anderen HTML-Statements.
Dem TreeView werden noch zwei Parameter mitgegeben: Der eine dient einfach zur Identifizierung
des Controls, der andere gibt an, wo sich die zu verwendenden Bilder befinden. Bei diesen Bildern
handelt es sich um die Bitmaps für die "+"- und "-"-Zeichen im Baum sowie um weitere Bitmaps, die
für die Baumdarstellung benötigt werden.
Innerhalb des Controls werden dann die Knoten (TreeNodes) eingefügt. Die Knoten können dabei
verschachtelt werden: Diese Verschachtelung der Knoten führt dann in der Browser-Anzeige zum Bild
des Baumes.
Im einfachsten Fall ist ein Knoten vollständig inline definiert. Unter Weglassen von Attributen wie dem
zu verwendenden Font oder der zu verwendenden Farben hat eine solche Knotendefinition folgendes
Aussehen:
> <ie:TreeNode IMAGEURL=" /webctrl_client/1_0/images/html.gif" TEXT="text1"
NAVIGATEURL="seite1.html" />
>
Innerhalb des Knotens gibt es die Eigenschaft IMAGEURL, die das Bild für den Knoten festlegt. Für
aufklappbare Knoten existiert die zusätzliche Eigenschaft EXPANDEDIMAGEURL, die für den Knoten
im aufgeklappten Zustand zuständig ist.
Der Parameter TEXT ist für den neben dem Knoten anzuzeigenden Text zuständig. Schließlich gibt es
noch die EigenschaftNAVIGATEURL. Diese legt die URL fest, zu der der Anwender bei einem Klick
auf den Text navigieren soll. Man kann sich relativ leicht vorstellen, dass die Nutzung des Controls in
diesem Zusammenhang hauptsächlich innerhalb eines Frame Sinn macht. Ansonsten müsste der
Baum in jeder einzelnen Seite enthalten sein, zu der navigiert werden soll.
Knoten auslagern mit XML Islands
Stammen die Daten eines Knoten aus einem XML-Island, dann muss dieses Island wie folgt
aufgebaut sein:
> <TREENODES>
> <treenode Text="Topnode 1">
> <treenode Text="Knoten 1.1" />
> <treenode Text="KNoten 1.2" />
> <treenode Text="Knoten 1.3" />
> </treenode>
> <treenode Text="Topnode 2" >
> <treenode Text="Knoten 2.1" />
> <treenode Text="Knoten 2.2" />
> <treenode Text="Knoten 2.3" />
> </treenode>
> </TREENODES>
>
Eingeschlossen wird das Island von einem <TREENODES>-Tag. Darin enthalten sind alle Knoten des
Island. Diese setzen sich aus ganz normalen TreeNode-Statements zusammen. Im Beispielcode
sehen Sie dabei auch ein Beispiel für die Verschachtelung von Knoten.
Den kompletten Beispielcode mit einer funktionierenden ASPX-Seite und einem zugehörigen XMLIsland gibt es bei tecCHANNEL.de zum Download (webcode: windowscompact).
DataGrid-Control
Ein anderes interessantes Server-seitiges Control ist das ASP DataGrid. Ähnlich wie das RepeaterControl oder die DataList dient das DataGrid-Control der Anzeige von Daten. Dabei ist es aber nicht
so, dass diese Daten unbedingt immer aus einer Datenbank kommen müssen: Datenquellen praktisch
beliebiger Art lassen sich an das DataGrid binden. Immer wenn Sie Daten in einer Form vorliegen
haben, in der das .NET Framework darüber iterieren kann, sind diese auch als Eingabewerte für das
DataGrid verwendbar. Das macht die Sache interessant, denn iterieren lässt sich über praktisch jede
Sammlung in .NET.
Angenommen, Sie haben ein Verzeichnis auf Ihrem Server, in dem die Download-Dateien gesammelt
werden. Auch in einem solchen Fall können Sie das ASP Datagrid verwenden, um diese Liste
anzuzeigen – und das mit ganz wenigen Codezeilen.
Welche der Dateiinformationen dabei angezeigt werden, bleibt Ihnen überlassen, denn wenn sich eine
Sammlung aus Objekten zusammensetzt, dann kann man beim Binden der Daten an das GridControl
angeben, welche der Eigenschaften aus den Ausgangsobjekten angezeigt werden sollen.
ASP bietet deutlich weniger Funktionalität als ASP.NET
Um die Dateiliste anzuzeigen, brauchen Sie erst einmal eine programmatisch verwendbare Liste der
Dateien aus dem Download-Verzeichnis. Vor ASP.NET mussten Sie das FileSystem-Objekt bemühen.
Das ist jetzt nicht länger notwendig – es gibt deutlich bessere Möglichkeiten. Für den Zugriff auf das
FileSystem definiert .NET den Namespace System.IO mit einer Reihe von Objekten, die diese
Dateisystemzugriffe kapseln.
Eines der in diesem Namespace angebotenen Objekte ist DirectoryInfo. Dieses Objekt hat eine
Methode namens GetFiles(), die anhand einer Wildcard-Angabe ein Array aus FileInfo-Objekten
liefert. Sie bieten alle für eine Datei relevanten Informationen in Form von Properties an. Dieses Array
eignet sich auch als Datensammlung für ein DataGrid: Man kann also ganz einfach eine Dateiliste in
einer DataGrid-Tabelle anzeigen lassen.
Dazu legen Sie zunächst eine neue Webanwendung an. Im Beispiel wird dafür C# verwendet. Der
benötigte Code ist aber minimal, eine Umstellung auf eine VB-Variante daher kein großes Problem.
Drag-and-Drop: Das DataGrid-Control ziehen Sie einfach aus der Toolbox auf ein Webform.
Auf das Form der WebApplication ziehen Sie dann ein DataGrid-Control. In dessen Eigenschaften
stellen Sie AutoGenerateCollumns auf false und legen stattdessen die gewünschten Spalten von
Hand in der Columns-Collection in den Eigenschaften an. Im Beispielcode wurden Spalten für den
Dateinamen, das Datum des letzten Schreibzugriffs und die Dateigröße angelegt. Diese drei Spalten
müssen dabei nicht nur den Titeltext erhalten, es sind auch die Namen der Properties aus dem
FileInfo-Objekt anzugeben: Dies sind Name, LastWriteTime und Length.
Natürlich kann man das Grid nun noch ein wenig hübscher formatieren, indem man alternierende
Farben und unterschiedliche Fonts für die Überschriften angibt: Notwendig ist das aber nicht. Wichtig
ist hingegen, der ID des Grid einen Namen zu geben, den man sich merken kann. Dieser Name wird
dann gleich im C#-Code benötigt. Im Beispiel hat das Grid den Namen fileList.
3 Zeilen Code: Daten ans Grid binden
Mit dem so definierten Grid sind Sie schon fast fertig. Alles was nun noch fehlt, ist ein wenig Code, der
eine Dateiliste ermittelt und die Objekte darin an das Grid bindet. Das tun Sie am besten im Event
Load des Form. Um einen Handler für dieses Event zu erzeugen, machen Sie einen Doppelklick auf
das Form. Das Visual Studio legt dann eine passende C#-Datei an, in der auch schon der leere EventHandler eingetragen ist. Dort findet sich zudem eine Instanz vom Typ DataGrid mit dem Namen
fileList. Das ist genau das DataGrid-Objekt, das Sie zuvor im HTML-Editor auf das Form gezogen
haben.
Der Handler selbst ist nicht sonderlich aufwendig:
> private void Page_Load(object sender, System.EventArgs e)
> {
> DirectoryInfo dirInfo = new DirectoryInfo( Server.MapPath(""));
> fileList.DataSource = dirInfo.GetFiles("*.*");
> fileList.DataBind();
> }
>
Zunächst wird ein neues DirectoryInfo-Objekt erzeugt. Damit das wie im Beispielcode gelingt, müssen
Sie oben im Code ein Statement der Form using System.IO einfügen. Andernfalls müssten Sie das
DirectoryInfo-Objekt mit seinem kompletten Namen erzeugen.
Eigenschaften: Mit dem Forms-Editor wählen Sie auch die anzuzeigenden Spalten aus der gebundenen Sammlung aus.
Im Beispiel wird einfach ein DirectoryInfo-Objekt für das Root-Verzeichnis des aktuellen virtuellen
Verzeichnisses ermittelt. Dieses Objekt wird dann nach allen Dateien gefragt. Statt dem Wildcard *.*
können Sie natürlich auch beliebige andere Angaben verwenden.
Die Ermittlung dieser Dateiliste erfolgt mit GetFiles() – und das Resultat wird dann einfach als
DataSource an das fileList-Objekt übergeben. Danach müssen Sie das Grid nur noch dazu bewegen,
die Daten auszuwerten. Das erfolgt mit dem abschließenden Aufruf von fileList.DataBind().
In diesem Beitrag haben Sie erfahren, wie einfach es ist, die Server Controls von .NET einzusetzen,
um auch Webseiten mit komplexen Controls zu gestalten, ohne auf die Client-Browser Rücksicht
nehmen zu müssen. Das TreeControl und das DataGrid-Control sind dabei sicherlich die
aufwendigeren der Server-seitigen Controls – doch auch die anderen angebotenen Elemente haben
eine Menge zu bieten. Es lohnt sich auf jeden Fall, ASP.NET mit einem etwas ausführlicheren Blick zu
untersuchen.
Der Autor Thomas Wölfer (www.woelfer.com) programmiert Baustatik-Software hauptsächlich in c++ und c# für D.I.E. Software
(www.die.de). Nebenher schreibt er Artikel rund um die Software-Entwicklung mit C++ und C#, den Betrieb von Servern und ITSicherheitsthemen – zum Beispiel für tecChannel.de. Weitere Informationen von Wölfer finden Sie unter www.die.de/blog.
© tecCHANNEL.de
Herunterladen