Inhalt
Vorwort
1 Wie .NET und ASP.NET funktionieren
2 Installation
3 Hinweise zu VB.NET
4 »Hallo, Welt!« – Ein ASP.NET-Crashkurs
5 Die Page-Klasse
6 HTML-Serversteuerelemente
7 Validierung von Anwendereingaben
8 Webserversteuerelemente
9 Webserversteuerelemente für die Darstellung von Listen
10 Webserversteuerelemente selbst erstellen
11 Der Status von Seiten, Sitzungen und Applikationen
12 ASP.NET und Datenbanken
13 »Wer darf was?« ASP.NET und Sicherheit
14 Webanwendungen erstellen und konfigurieren
15 Leistungssteigerung durch Caching
16 Web Services
A Anhang
Index
Download (ca 14,3 MB)
Buch bestellen (29,90 EUR)
Ihre Meinung?@
<< zurück | Galileo Computing / <openbook> / Einstieg in ASP.NET | vor >>
Einstieg in ASP.NET von Matthias Lohrer
| Kapitel 12 ASP.NET und Datenbanken
|  | 12.1 Auf Datenbanken zugreifen – ein Crashkurs
|  |  | 12.1.1 Eine Tabelle im Browser anzeigen
|  |  | 12.1.2 Über den Browser einen Datensatz hinzufügen
|  | 12.2 Wie ADO.NET funktioniert – ein Überblick
|  | 12.3 Die Verbindung zur Datenbank herstellen
|  |  | 12.3.1 OleDbConnection
|  |  | 12.3.2 SqlConnection
|  | 12.4 Daten lesen mit SqlCommand und OleDbCommand
|  |  | 12.4.1 ExecuteReader
|  |  | 12.4.2 ExecuteNonQuery und die Parameters-Collection
|  |  | 12.4.3 ExecuteScalar
|  | 12.5 SqlDataReader und OleDbDataReader
|  |  | 12.5.1 Ein Reader-Objekt an ein Steuerelement binden
|  |  | 12.5.2 Ein Reader-Objekt an ein Listensteuerelement binden
|  |  | 12.5.3 Ein Reader-Objekt zeilenweise auswerten
|  | 12.6 Die DataSet-Klasse
|  |  | 12.6.1 Das Zusammenspiel von Command, Adapter und DataSet
|  |  | 12.6.2 Mehrere Tabellen in ein DataSet-Objekt einlesen
|  |  | 12.6.3 Auf einzelne Zeilen, Spalten und Tabellen eines DataSet-Objekts gezielt zugreifen
|  |  | 12.6.4 Relationen zwischen Tabellen festlegen
|  | 12.7 DataViews verwenden
|  |  | 12.7.1 Tabellen sortieren
|  |  | 12.7.2 Tabellen nach Inhalten filtern
|  |  | 12.7.3 Nach dem Zeilenstatus filtern
|  |  | 12.7.4 In Tabellen suchen
|  | 12.8 Mit ASP.NET Daten bearbeiten
|  | 12.9 Daten bearbeiten mit dem Command-Objekt
|  | 12.10 In-Place-Editing mit dem DataGrid-Steuerelement
|  |  | 12.10.1 Die EditItemIndex-Eigenschaft
|  |  | 12.10.2 Das asp:DataGrid-Tag anpassen
|  |  | 12.10.3 OnEditCommand: Daten bearbeiten
|  |  | 12.10.4 OnCancelCommand: Die Bearbeitung abbrechen
|  |  | 12.10.5 OnUpdateCommand: Die Änderungen sichern
|  |  | 12.10.6 Das Repeater-Steuerelement verwenden
|  |  | 12.10.7 Die Ereignisse des Repeater-Steuerelements auswerten
|  | 12.11 Das DataList-Steuerelement
|  |  | 12.11.1 In-Place-Editing mit dem DataList-Steuerelement
## 12.10 In-Place-Editing mit dem DataGrid-Steuerelement Das DataGrid-Steuerelement bietet die Möglichkeit, Daten im In-Place-Editing-Modus zu bearbeiten. Für die Realisierung dieses anwenderfreundlichen Verfahrens müssen mehrere ASP.NET-Zahnräder korrekt ineinander greifen. Die folgenden Erläuterungen stellen die benötigten Bestandteile nacheinander einzeln vor. Am Anfang steht Code, der nur einen Teil der benötigten Funktionalität umsetzt. Schritt für Schritt kommen weitere Elemente dazu, bis am Schluss der gesamte Bearbeitungszyklus funktioniert. ### 12.10.1 Die EditItemIndex-Eigenschaft Wenn Sie die voreingestellten Standardeigenschaften des DataGrid-Steuerelements verwenden und das Steuerelement an eine Tabelle als Datenquelle binden, dann ist das Ergebnis im Browser eine ganz einfache Tabelle ohne Besonderheiten. Das DataGrid-Steuerelement bietet einige Schalter, mit denen Sie die Darstellung und auch die Funktionalität dieser Tabelle erweitern können. Für die Bearbeitung von Daten kommt der Eigenschaft EditItemIndex eine zentrale Bedeutung zu. Der Eigenschaft EditItemIndex übergeben Sie die Ordnungszahl des Datensatzes, den Sie bearbeiten möchten. Wenn Sie anschließend das DataGrid-Steuerelement mit Daten füllen, hat die neu erstellte Tabelle eine Besonderheit: Die Felder des Datensatzes, den Sie in EditItemIndex angegeben haben, werden jetzt mit Hilfe von Eingabefeldern dargestellt. Der Anwender kann den Inhalt dieses Datensatzes bearbeiten. Damit ergibt sich folgende charakteristische Codesequenz:
       ' Der vierte Datensatz soll bearbeitet werden.
       ' Zur Basis Null ergibt sich eine 3
       myGrid.EditItemIndex = 3
       ' ...
       ' Datenbankverbindung aufbauen
       ' ...
       sql = "SELECT * FROM Versandfirmen"
       Dim cmd As New OleDbCommand(sql, conn)
       ' Das DataGrid-Steuerelement mit Daten füllen
       myGrid.DataSource = cmd.ExecuteReader()
       ' Wegen der gesetzten EditItemIndex-Eigenschaft
       ' wird eine Zeile im Bearbeitungsmodus angezeigt
       DataBind()
Der Code legt zunächst fest, welcher Datensatz bearbeitet werden soll, indem er die Eigenschaft EditItemIndex entsprechend setzt. Anschließend wird durch den Aufruf von ExecuteReader() wie gewohnt die Datenquelle des DataGrid-Steuerelements gefüllt. Die betroffene Zeile kann nun bearbeitet werden. Wenn der Editiervorgang abgeschlossen ist und die Tabelle wieder in der normalen Form angezeigt werden soll, setzen Sie die Eigenschaft EditItemIndex auf -1. Das ist das Signal für das DataGrid-Steuerelement, dass keine Zeile bearbeitet werden soll. Wenn Sie damit erneut ExecuteReader() aufrufen, erscheint wieder die normale Tabelle ohne Besonderheiten. db_17.aspx realisiert diesen ersten Schritt im Zusammenhang. Abbildung 12.18 zeigt die Darstellung im Browser. Die dritte Zeile kann bearbeitet werden, aber bislang gibt es noch keine Möglichkeit, die Änderungen zu speichern oder einen anderen Datensatz zu bearbeiten. Der Code muss also noch entsprechend erweitert werden. Abgesehen von der Verwendung der Eigenschaft EditItemIndex wird in db_17.aspx auch die Deklaration des asp:DataGrid-Tags im HTML-Teil der aspx-Seite angepasst. Diese Änderungen werden im nächsten Abschnitt erläutert.
    <!-- db_17.aspx -->
    <%@ Page Language="VB" Debug="True" Strict="True" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.OleDb" %>
    <script runat="server">
    Sub Page_Load (ByVal Sender As Object, _
                   ByVal E As EventArgs)
       ' Verbindungszeichenfolge zusammensetzen
       Dim connStr As String
       connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
       connStr += _
      "Data Source=E:\ASPdotNETBuch\Listings\Nordwind.mdb;"
       ' Verbindung zur Datenbank herstellen
       Dim conn As New OleDbConnection(connStr)
       conn.Open()

       ' Der dritte Datensatz soll bearbeitet werden
       myGrid.EditItemIndex = 2

       ' Die Tabelle Versandfirmen anzeigen
       Dim sql As String
       sql = "SELECT * FROM Versandfirmen"
       Dim cmd As New OleDbCommand(sql, conn)
       myGrid.DataSource = cmd.ExecuteReader()
       DataBind()
       conn.Close()
    End Sub
    </script>
    <html><head><title>In-Place-Editing mit dem
    DataGrid-Steuerelement, Schritt 1</title></head>
    <body>
    <h3>In-Place-Editing mit dem
    DataGrid-Steuerelement<br>Schritt 1</h3>
    <form runat="server" >
    <asp:DataGrid id="myGrid" runat="server"
                  AutoGenerateColumns="false" >
    <Columns>
       <asp:BoundColumn
            DataField="Firma"
            HeaderText="Firma" />
       <asp:BoundColumn
            DataField="Telefon"
            HeaderText="Telefon" />
    </Columns>
    </asp:DataGrid>
    </form></body></html>
### 12.10.2 Das asp:DataGrid-Tag anpassen Wenn Sie das DataGrid-Steuerelement in der einfachsten Form verwenden, gibt das Steuerelement die zugrunde liegenden Daten in der Standardform aus.
    <asp:DataGrid id="myGrid" runat="server" />
Diese Standardausgabeform enthält alle Spalten und Zeilen und keine Daten sind in irgendeiner Form hervorgehoben. Wenn Sie nicht alle Spalten ausgeben möchten oder zusätzliche Spalten ausgeben wollen oder wenn Sie einzelne Spalten in irgendeiner Form hervorheben möchten, dann realisieren Sie diese individuelle Gestaltung in zwei Schritten: Hier klicken, um das Bild zu Vergrößern Abbildung 12.18 Die EditItemIndex-Eigenschaft des DataGrid-Steuerelements enthält die Ordnungszahl der zu bearbeitenden Zeile. 1. Sie verwenden das Attribut AutoGenerateColumns="false" im asp:DataGrid-Steuerelement. 2. Sie fügen innerhalb des asp:DataGrid-Elements ein Element Columns hinzu, in dem Sie die gewünschten Spalten beschreiben. In db_17.aspx sieht das Ergebnis so aus:
    <asp:DataGrid id="myGrid" runat="server"
                  AutoGenerateColumns="false" >
    <Columns>
       <asp:BoundColumn
            DataField="Firma"
            HeaderText="Firma" />
       <asp:BoundColumn
            DataField="Telefon"
            HeaderText="Telefon" />
    </Columns>
    </asp:DataGrid>
Das ist noch wenig spektakulär. Das Ergebnis unterscheidet sich von der Standardausgabe zunächst nur darin, dass das Feld Firmen-Nr nicht mit aufgeführt wird. Innerhalb des Columns-Elements definieren Sie mit Hilfe weiterer Elemente die Merkmale der einzelnen Spalten. ASP.NET stellt fünf vordefinierte Spaltentypen zur Verfügung, die sich jeweils individuell anpassen lassen:
| BoundColumn ist der Standardspaltentyp. Die Spalte ist an die Inhalte einer Spalte der Datenquelle gebunden.
| HyperLinkColumn, ButtonColumn und TemplateColumn bieten weiter gehende Möglichkeiten, die hier zunächst noch nicht interessieren sollen.
| Eine Spalte vom Typ EditCommandColumn benötigen wir, um für jede Zeile die Bearbeitungsbefehle angeben zu können.
Das Beispiel verwendet zunächst nur den Spaltentyp BoundColumn. Im Attribut DataField geben Sie den Namen der gewünschten Spalte an. Im Attribut HeaderText legen Sie den Text für den Spaltenkopf fest. Als nächsten Schritt ergänzen Sie eine Spalte vom Typ EditCommandColumn hinter den beiden Datenspalten. Das Columns-Element bekommt damit diese Form:
    <Columns>
       <asp:BoundColumn
            DataField="Firma"
            HeaderText="Firma" />
       <asp:BoundColumn
            DataField="Telefon"
            HeaderText="Telefon" />
       <asp:EditCommandColumn
            EditText="Bearbeiten"
            CancelText="Abbrechen"
            UpdateText="Speichern"
            HeaderText="Bearbeitung" />
    </Columns>
Weitere Änderungen müssen Sie an db_17.aspx nicht vornehmen. db_18.aspx enthält diese erweiterte Form. Bei einem Blick auf die Darstellung im Browser (siehe Abbildung 12.19) wird deutlich, wie das asp:EditCommandColumn-Element arbeitet. Zeilen, die nicht bearbeitet werden, erhalten in der Spalte Bearbeitung einen Link Bearbeiten. Die Zeile, die momentan bearbeitet wird, erhält in dieser Spalte zwei Links: Speichern und Abbrechen. Diese Bezeichnungen haben Sie mit den Attributen EditText="Bearbeiten", CancelText="Abbrechen", UpdateText="Speichern" und HeaderText="Bearbeitung" im asp:EditCommandColumn-Element festgelegt. Hier klicken, um das Bild zu Vergrößern Abbildung 12.19 Der Spaltentyp EditCommandColumn stellt die typischen Bearbeitungsfunktionen zur Verfügung. Wenn Sie die Links anklicken, passiert noch nichts. Die Funktionalität für diese Links müssen Sie erst noch erstellen. Sie weisen den Links eine Funktion zu, indem Sie für jede Funktion eine entsprechende Prozedur erstellen und im asp:DataGrid-Element die Attribute OnEditCommand, OnCancelCommand und OnUpdateCommand definieren. Wenn Ihre Ereignisprozeduren myGridEdit, myGridCancel und myGridUpdate heißen, erhält das Start-Tag von asp:DataGrid diese Form:
    <asp:DataGrid id="myGrid" runat="server"
                  AutoGenerateColumns="false"
                  OnEditCommand="myGridEdit"
                  OnCancelCommand="myGridCancel"
                  OnUpdateCommand="myGridUpdate" >
In den folgenden Abschnitten werden diese zu erstellenden Ereignisprozeduren erläutert. ### 12.10.3 OnEditCommand: Daten bearbeiten Was soll passieren, wenn ein Anwender in der Spalte Bearbeitung den Link Bearbeiten anklickt? Der Anwender erwartet, dass anschließend die Inhalte der Spalten in Textfeldern angezeigt werden, die er bearbeiten kann. Außerdem soll die Spalte Bearbeitung die Einträge Speichern und Abbrechen bekommen. Wie lassen sich diese Anforderungen umsetzen? Zwei Schritte reichen aus: 1. Setzen Sie die EditItemIndex-Eigenschaft des DataGrid-Steuerelements auf die Nummer des zu bearbeitenden Datensatzes. 2. Veranlassen Sie, dass die Tabelle neu gezeichnet wird. Das DataGrid-Steuerelement wird dann beim Neuzeichnen sämtliche Änderungen in der Darstellung selbstständig vornehmen. Der Schritt 2 wird auch bei den anderen Ereignisprozeduren für das Sichern und das Abbrechen immer wieder benötigt. Also lagern Sie diesen Vorgang in eine separate Prozedur aus, die Sie an mehreren Stellen aufrufen können. Im Beispiel bekommt diese Prozedur den Namen anzeigeAktualisieren(). Für die Ereignisprozedur myGridEdit bleiben damit nur noch zwei Zeilen Code übrig:
    Public Sub myGridEdit _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
       myGrid.EditItemIndex = E.Item.ItemIndex
       anzeigeAktualisieren()
    End Sub
Die entscheidende Frage für diese Prozedur lautet, wie sie ermitteln kann, in welcher Zeile der Anwender Bearbeiten angeklickt hat. Diese Information ist über das DataGridCommandEventArgs-Objekt E zugänglich. Über die Eigenschaft Item des DataGridCommandEventArgs-Objekts erreichen Sie das Element mit der Befehlsquelle in Form eines DataGridItem-Objekts. Dessen Indexposition ermitteln Sie über die ItemIndex-Eigenschaft. Indem Sie diesen Wert der Eigenschaft myGrid.EditItemIndex zuweisen, ist auch schon alles für die Anzeige der Tabelle mit Bearbeitungsfunktion vorbereitet. Die Prozedur anzeigeAktualisieren enthält den bereits bekannten Code, der bislang innerhalb von Page_Load() ablief. Wenn Sie den Code hier herausnehmen, müssen Sie sich noch etwas für den Fall überlegen, dass das Skript erstmalig aufgerufen wird. In diesem Fall soll die Tabelle ganz normal angezeigt werden, womit für Page_Load diese drei Zeilen übrig bleiben:
       If Not IsPostBack() Then
          anzeigeAktualisieren()
       End If
Da Sie im asp:DataGrid-Steuerelement auch bereits die Attribute OnCancelCommand="myGridCancel" und OnUpdateCommand="myGridUpdate" gesetzt haben, fügen Sie hierfür jeweils noch leere Prozeduren hinzu, damit beim Kompilieren keine Fehlermeldung ausgegeben wird. db_19.aspx fasst die Änderungen zusammen, die Sie bis zu diesem Punkt am Code vorgenommen haben.
    <!-- db_19.aspx -->
    <%@ Page Language="VB" Debug="True" Strict="True" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.OleDb" %>
    <script runat="server">
    Public Sub anzeigeAktualisieren()
       ' Verbindungszeichenfolge zusammensetzen
       Dim connStr As String
       connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
       connStr += _
      "Data Source=E:\ASPdotNETBuch\Listings\Nordwind.mdb;"
       ' Verbindung zur Datenbank herstellen
       Dim conn As New OleDbConnection(connStr)
       conn.Open()
       ' Die Tabelle Versandfirmen anzeigen
       Dim sql As String
       sql = "SELECT * FROM Versandfirmen"
       Dim cmd As New OleDbCommand(sql, conn)
       myGrid.DataSource = cmd.ExecuteReader()
       DataBind()
       conn.Close()
    End Sub

    Sub Page_Load (ByVal Sender As Object, _
                   ByVal E As EventArgs)
       If Not IsPostBack() Then
          anzeigeAktualisieren()
       End If
    End Sub

    Public Sub myGridEdit _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
       myGrid.EditItemIndex = E.Item.ItemIndex
       anzeigeAktualisieren()
    End Sub

    Public Sub myGridCancel _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
    End Sub

    Public Sub myGridUpdate _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
    End Sub
    </script>
    <html><head><title>In-Place-Editing mit dem
    DataGrid-Steuerelement, Schritt 3: Das
    EditCommand-Ereignis behandeln</title></head>
    <body>
    <h3>In-Place-Editing mit dem DataGrid-Steuerelement<br>
    Schritt 3: Das EditCommand-Ereignis behandeln
    </h3>
    <form runat="server" >
    <asp:DataGrid id="myGrid" runat="server"
                  AutoGenerateColumns="false"
                  OnEditCommand="myGridEdit"
                  OnCancelCommand="myGridCancel"
                  OnUpdateCommand="myGridUpdate" >
    <Columns>
       <asp:BoundColumn
            DataField="Firma"
            HeaderText="Firma" />
       <asp:BoundColumn
            DataField="Telefon"
            HeaderText="Telefon" />
       <asp:EditCommandColumn
            EditText="Bearbeiten"
            CancelText="Abbrechen"
            UpdateText="Speichern"
            HeaderText="Bearbeitung" />
    </Columns>
    </asp:DataGrid>
    </form></body></html>
Die Änderungen, die Sie bis hierhin durchgeführt haben, bewirken, dass Sie hinter jeder Zeile Bearbeiten anklicken können und dass anschließend diese Zeile in den Bearbeitungsmodus wechselt. Als Nächstes sind die Funktionen für das Abbrechen und für das Speichern der Änderungen zu erstellen. ### 12.10.4 OnCancelCommand: Die Bearbeitung abbrechen Die Prozedur für das Abbrechen des Editiervorgangs ist denkbar einfach. So, wie Sie bei myGridEdit die Zeile angeben, die bearbeitet werden soll, geben Sie bei myGridCancel an, dass keine Zeile bearbeitet werden soll. Dafür setzen Sie die Eigenschaft myGrid.EditItemIndex auf -1 und so kommt auch myGridCancel mit zwei Zeilen Code aus:
    Public Sub myGridCancel _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
       myGrid.EditItemIndex = -1
       anzeigeAktualisieren()
    End Sub
### 12.10.5 OnUpdateCommand: Die Änderungen sichern Im Vergleich zu den beiden anderen Ereignisprozeduren hat myGridUpdate richtig viel zu tun. Hier zunächst der Code, im Anschluss daran die Erläuterungen.
    Public Sub myGridUpdate _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
       Dim connStr As String
       connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
       connStr += _
      "Data Source=E:\ASPdotNETBuch\Listings\Nordwind.mdb;"
       Dim conn As New OleDbConnection(connStr)
       conn.Open()
       Dim sqlUpdate As String
       sqlUpdate = "UPDATE Versandfirmen SET Firma='"
       sqlUpdate &= _
          CType(E.Item.Cells(0).Controls(0), TextBox).Text
       sqlUpdate &= "', Telefon ='"
       sqlUpdate &= _
          CType(E.Item.Cells(1).Controls(0), TextBox).Text
       sqlUpdate &= "' WHERE [Firmen-Nr] = "
       sqlUpdate &= CStr(myGrid.DataKeys(E.Item.ItemIndex))
       Dim cmd As New OleDbCommand()
       cmd.Connection = conn
       cmd.CommandText = sqlUpdate
       cmd.ExecuteNonQuery()
       conn.Close()
       myGrid.EditItemIndex = -1
       anzeigeAktualisieren()
    End Sub
Der größte Teil des Codes ist bereits bekannt. Die Prozedur baut die Datenbankverbindung auf, setzt einen SQL-Befehl für ein Datenbank-Update zusammen und führt ihn mit Hilfe eines OleDbCommand-Objekts aus. Im Anschluss wird myGrid.EditItemIndex auf -1 gesetzt und die Tabellendarstellung aktualisiert, so dass keine Zeile mehr bearbeitet wird. Es stellen sich zwei neue Aufgaben: 1. Sie müssen die Eingaben des Anwenders ermitteln. 2. Zur eindeutigen Identifizierung des Datensatzes benötigen Sie die Angabe der Firmen-Nr. Die Tabelle selbst enthält die Firmen-Nr. aber nicht. #### Die Eingaben des Anwenders ermitteln Der vom Anwender editierte Firmenname versteckt sich hinter diesem Ausdrucksungetüm:
    CType(E.Item.Cells(0).Controls(0), TextBox).Text
Dieser Ausdruck verwendet zweimal die Default-Eigenschaft Item. Wenn man diese Default-Eigenschaft zusätzlich ausdrücklich hinschreibt, ergibt sich diese Form: CType(E.Item.Cells.Item(0).Controls.Item(0), TextBox).Text Dieser Ausdruck soll Schritt für Schritt aufgelöst werden.
| E E Der Ereignisprozedur myGridUpdate wurde in der Variablen E ein Objekt vom Typ DataGridCommandEventArgs übergeben.
| E E.Item Die Eigenschaft Item von E gibt ein Objekt vom Typ DataGridItem zurück. Ein DataGridItem repräsentiert eine Zeile eines DataGrid-Objekts.
| E E.Item.Cells Die Eigenschaft Cells dieses DataGridItem-Objekts führt zu der von TableRow geerbten Cells-Eigenschaft, die ihrerseits ein Objekt vom Typ TableCellCollection enthält.
| E E.Item.Cells.Item(0) oder verkürzt E.Item.Cells(0) Über die Default-Eigenschaft Item(nummer) erreichen Sie das einzelne TableCell-Objekt. Die erste Zelle enthält den Firmennamen.
| E E.Item.Cells(0).Controls Die einzelne Zelle enthält mehrere Controls. Die Klasse TableCell kennt die Eigenschaft Controls, die ein Objekt vom Typ ControlCollection enthält.
| E E.Item.Cells(0).Controls.Item(0) oder verkürzt E.Item.Cells(0).Controls(0) Über die Default-Eigenschaft Item (nummer) der ControlCollection erreichen wir das einzelne Control-Objekt. Das erste Control-Objekt ist das Texteingabefeld: Controls(0).
| E CType(E.Item.Cells(0).Controls(0), TextBox) Ein Control-Objekt hat etwas nicht: Es hat keine Value- oder Text-Eigenschaft, mit der sich der Inhalt des Eingabefeldes unmittelbar auslesen ließe. Sie müssen das Control-Objekt erst wieder zu dem machen, was es eigentlich ist, nämlich ein Objekt vom Typ TextBox. Dazu verwenden Sie die Konvertierungsfunktion CType.
| E CType(E.Item.Cells(0).Controls(0), TextBox).Text Das TextBox-Objekt hat schließlich eine Eigenschaft Text, die den vom Anwender editierten Text enthält.
Damit haben Sie erfolgreich den geänderten Firmennamen ermittelt. Um die geänderte Telefonnummer zu ermitteln, reicht es aus, mit E.Item.Cells(1) die zweite Zelle zu adressieren. Der Rest des Ausdrucks bleibt gleich. #### Den Wert des Schlüsselfeldes ermitteln Für den SQL-Befehl, der das Datenbank-Update ausführen soll, benötigen Sie auf jeden Fall den Wert des Schlüsselfeldes. Er muss in der Klausel WHERE [Firmen-Nr] = xyz an der Stelle von xyz eingesetzt werden. Die Tabelle selbst enthält die Spalte Firmen-Nr jedoch nicht. Wie also können Sie diesen Wert ermitteln?
Tipp So geht's: Bei der Deklaration des asp:DataGrid-Steuerelements fügen Sie das Attribut DataKeyField="Firmen-Nr" hinzu. Damit teilen Sie dem DataGrid-Steuerelement mit, dass diese Spalte die Schlüssel enthält.
Im Code der Prozedur myGridUpdate ermitteln Sie den zugehörigen Schlüssel-Wert mit diesem Ausdruck:
    CStr(myGrid.DataKeys(E.Item.ItemIndex))
Die DataKeys-Eigenschaft des DataGrid-Objekts ruft ein Objekt vom Typ DataKeyCollection ab. Diese Auflistung enthält die Schlüsselwerte aller Datensätze. Von der Deklaration DataKeyField="Firmen-Nr" weiß das Steuerelement, dass es hier die Spalte Firmen-Nr verwenden soll. Auf den einzelnen Wert greifen Sie über die Default-Eigenschaft Item zu. Den Schlüsselwert des dritten Datensatzes würden Sie also über myGrid.DataKeys.Item(2) beziehungsweise myGrid.DataKeys(2) ansprechen. Es bleibt die Aufgabe, die Nummer des bearbeiteten Datensatzes zu ermitteln. Das Verfahren kennen Sie bereits aus den beiden anderen Ereignisprozeduren: E.Item.Itemindex liefert den gesuchten Wert. myGrid.DataKeys(E.Item.ItemIndex) gibt ein Objekt vom Typ Object zurück. Mit CStr wandeln Sie das Objekt in einen String um. Damit haben Sie den Schlüsselwert ermittelt und können ihn in den SQL-Befehl einbauen. Damit ist der komplette Bearbeitungszyklus umgesetzt. db_20.aspx zeigt den kompletten Code im Zusammenhang.
    <!-- db_20.aspx -->
    <%@ Page Language="VB" Debug="True" Strict="True" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.OleDb" %>
    <script runat="server">
    Public Sub anzeigeAktualisieren()
       ' Verbindungszeichenfolge zusammensetzen
       Dim connStr As String
       connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
       connStr += _
      "Data Source=E:\ASPdotNETBuch\Listings\Nordwind.mdb;"
       ' Verbindung zur Datenbank herstellen
       Dim conn As New OleDbConnection(connStr)
       conn.Open()
       ' Die Tabelle Versandfirmen anzeigen
       Dim sql As String
       sql = "SELECT * FROM Versandfirmen"
       Dim cmd As New OleDbCommand(sql, conn)
       myGrid.DataSource = cmd.ExecuteReader()
       DataBind()
       conn.Close()
    End Sub

    Sub Page_Load (ByVal Sender As Object, _
                   ByVal E As EventArgs)
       If Not IsPostBack() Then
          anzeigeAktualisieren()
       End If
    End Sub

    Public Sub myGridEdit _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
       myGrid.EditItemIndex = E.Item.ItemIndex
       anzeigeAktualisieren()
    End Sub

    Public Sub myGridCancel _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
       myGrid.EditItemIndex = -1
       anzeigeAktualisieren()
    End Sub

    Public Sub myGridUpdate _
                  (ByVal Sender As Object, _
                   ByVal E As DataGridCommandEventArgs)
       ' Verbindungszeichenfolge zusammensetzen
       Dim connStr As String
       connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
       connStr += _
      "Data Source=E:\ASPdotNETBuch\Listings\Nordwind.mdb;"
       Dim conn As New OleDbConnection(connStr)
       conn.Open()
       Dim sqlUpdate As String
       sqlUpdate = "UPDATE Versandfirmen SET Firma='"
       sqlUpdate &= _
          CType(E.Item.Cells(0).Controls(0), TextBox).Text
       sqlUpdate &= "', Telefon ='"
       sqlUpdate &= _
          CType(E.Item.Cells(1).Controls(0), TextBox).Text
       sqlUpdate &= "' WHERE [Firmen-Nr] = "
       sqlUpdate &= CStr(myGrid.DataKeys(E.Item.ItemIndex))
       Dim cmd As New OleDbCommand()
       cmd.Connection = conn
       cmd.CommandText = sqlUpdate
       cmd.ExecuteNonQuery()
       conn.Close()
       myGrid.EditItemIndex = -1
       anzeigeAktualisieren()
    End Sub
    </script>
    <html><head><title>In-Place-Editing mit dem
    DataGrid-Steuerelement, Schritt 4: Die Ereignisse
    UpdateCommand und CancelCommand behandeln</title></head>
    <body>
    <h3>In-Place-Editing mit dem DataGrid-Steuerelement<br>
    Schritt 4: Die Ereignisse UpdateCommand und
    CancelCommand behandeln
    </h3>
    <form runat="server" >
    <asp:DataGrid id="myGrid" runat="server"
                  AutoGenerateColumns="false"
                  DataKeyField="Firmen-Nr"
                  OnEditCommand="myGridEdit"
                  OnCancelCommand="myGridCancel"
                  OnUpdateCommand="myGridUpdate" >
    <Columns>
       <asp:BoundColumn
            DataField="Firma"
            HeaderText="Firma" />
       <asp:BoundColumn
            DataField="Telefon"
            HeaderText="Telefon" />
       <asp:EditCommandColumn
            EditText="Bearbeiten"
            CancelText="Abbrechen"
            UpdateText="Speichern"
            HeaderText="Bearbeitung" />
    </Columns>
    </asp:DataGrid>
    </form></body></html>
### 12.10.6 Das Repeater-Steuerelement verwenden Das Repeater-Steuerelement kann ebenfalls an eine Datenquelle gebunden werden. Als DataSource kann jedes Objekt angegeben werden, das von System.Collections.IEnumerable abgeleitet ist. Neben Datenbanktabellen gehören dazu etwa auch Arrays oder die Klasse System.Collections.Hashtable. Das Repeater-Steuerelement gibt die Datensätze seiner Datenquelle in gleichmäßiger Form aus. Für die Gestaltung der Ausgabe kann der Entwickler maximal fünf Vorlagen in Form von HTML-Code erstellen:
| HeaderTemplate beschreibt den Anfang der Auflistung. Hier kann beispielsweise ein Tabellenkopf definiert werden.
| ItemTemplate legt die Ausgabeform für den einzelnen Datensatz fest.
| Den Raum zwischen den einzelnen Datensätzen gestalten Sie mit dem SeparatorTemplate.
| Wenn Sie die Daten in tabellarischer Form ausgeben, dann erhöht es die Lesbarkeit, wenn die Zeilen nicht alle gleich aussehen, sondern beispielsweise abwechselnd weiß und grau hinterlegt sind. Für diesen Effekt definieren Sie ein AlternatingItemTemplate, das sich in der Ausgabe stets mit ItemTemplate abwechselt.
| Zu guter Letzt schließen Sie die Darstellung mit dem FooterTemplate ab.
Bei der Deklaration eines Repeater-Steuerelements müssen Sie mindestens ein ItemTemplate definieren. Die übrigen Elemente sind optional. db_21.aspx gibt beispielhaft eine Liste der Versandunternehmen mit Telefonnummern aus, wie in Abbildung 12.20 zu sehen.
    <!-- db_21.aspx -->
    <%@ Page Language="VB" Debug="True" Strict="True"
             EnableViewstate="false" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.OleDb" %>
    <script runat="server">
    Sub Page_Load (ByVal Sender As Object, _
                   ByVal E As EventArgs)
       Dim connStr As String
       connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
       connStr += _
      "Data Source=C:\ASPdotNETBuch\Listings\Nordwind.mdb;"
       Dim conn As New OleDbConnection(connStr)
       conn.Open()
       Dim sql As String
       sql = "SELECT * FROM Versandfirmen"
       Dim cmd As New OleDbCommand(sql, conn)
       Dim myDataReader As OleDbDataReader
       myDataReader = cmd.ExecuteReader()
       myRepeat.DataSource = myDataReader
       myRepeat.DataBind()
       myDataReader.Close()
       conn.Close()
    End Sub
    </script>
    <html><head><title>
    Repeater-Steuerelement
    </title></head>
    <body>
    <h3>Repeater-Steuerelement</h3>
    <form runat="server">
    <asp:repeater id="myRepeat" runat="server" >

       <HeaderTemplate>
          Versandfirmen mit Tel-Nr.: <ul>
       </HeaderTemplate>

       <ItemTemplate>
          <li><%# DataBinder.Eval _
                          (Container.DataItem, "Firma") %>
          , <%# DataBinder.Eval _
                         (Container.DataItem, "Telefon")%>
       </ItemTemplate>

       <FooterTemplate>
          </ul>
       </FooterTemplate>

    </asp:repeater>
    </form>
    </body></html>
Hier klicken, um das Bild zu Vergrößern Abbildung 12.20 Maximal fünf verschiedene HTML-Vorlagen steuern die Ausgabe des Repeater-Steuerelements. db_21.aspx deklariert im HTML-Bereich das asp:repeater-Element. Es enthält drei Template-Elemente.
| Der HeaderTemplate legt den Beginn fest. Hier wird der Text Versandfirmen mit Tel-Nr.: ausgegeben und die ungeordnete Liste wird mit dem HTML-Tag <ul> eingeleitet.
| Das ItemTemplate legt die Ausgabeform für die einzelnen Datensätze fest. Es beginnt jeweils mit einem <li>-Tag. Der folgende Ausdruck sorgt dafür, dass die Firma ausgegeben wird. Es folgt ein Komma und abschließend die Telefonnummer.
| Zum Abschluss gibt das FooterTemplate das schließende Tag </ul> aus.
Die beiden anderen Templates verwendet dieses Beispiel nicht. Das SeparatorTemplate und das AlternatingItemTemplate sind vorwiegend bei der Ausgabe von Tabellen interessant. Die Page_Load-Prozedur enthält keine Neuigkeiten. Das OleDbDataReader-Objekt wird in gewohnter Manier erstellt und an die Eigenschaft myRepeat.DataSource gebunden. Anschließend sorgt myRepeat.DataBind() für die konkrete Ausführung der Datenbindung. Auf den ersten Blick ungewöhnlich ist die Ausgabe der Daten selbst innerhalb der Templates:
    <%# DataBinder.Eval (Container.DataItem, "Firma") %>
Die Klammersyntax <%# ... %> ist eine spezielle Syntax von ASP.NET für Datenbindungsausdrücke. Die statische Methode DataBinder.Eval kann spät gebundene Datenbindungsausdrücke auswerten und als Zeichenfolge darstellen. Diese Methode DataBinder.Eval erhält zwei Parameter. Bei der Verwendung innerhalb einer Vorlage wird als erster Parameter stets das Objekt Container.DataItem angegeben. Der zweite Parameter enthält den Feldnamen als String. ### 12.10.7 Die Ereignisse des Repeater-Steuerelements auswerten Abgesehen von den Ereignissen, die bereits die Basisklasse Control definiert, bietet das Repeater-Steuerelement drei Ereignisse:
| ItemCommand tritt ein, wenn innerhalb des Repeater-Elements eine Schaltfläche angeklickt wird.
| ItemCreated tritt ein, wenn im Repeater-Steuerelement ein Element erstellt wird.
| ItemDataBound tritt ein, nachdem ein Element an Daten gebunden, aber bevor es auf der Seite gerendert wurde.
db_22.aspx demonstriert, wie Sie innerhalb eines Repeater-Steuerelements in jeder Zeile eine Schaltfläche hinzufügen können. Wenn der Anwender eine Schaltfläche anklickt, wird unter der Tabelle die gewählte Nummer ausgegeben. Wenn die technischen Voraussetzungen gegeben sind, ließe sich hier eine Anwendung erstellen, die auf Mausklick die gewünschte Nummer wählt (siehe Abbildung 12.21).
    <!-- db_22.aspx -->
    <%@ Page Language="VB" Debug="True" Strict="True"
             EnableViewstate="true" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.OleDb" %>
    <script runat="server">
    Sub Page_Load (ByVal Sender As Object, _
                   ByVal E As EventArgs)
       If Not IsPostBack Then
          Dim connStr As String
          connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"
          connStr += _
      "Data Source=C:\ASPdotNETBuch\Listings\Nordwind.mdb;"
          ' Verbindung zur Datenbank herstellen
          Dim conn As New OleDbConnection(connStr)
          conn.Open()
          Dim sql As String
          sql = "SELECT * FROM Versandfirmen"
          Dim cmd As New OleDbCommand(sql, conn)
          Dim myDataReader As OleDbDataReader
          myDataReader = cmd.ExecuteReader()
          myRepeat.DataSource = myDataReader
          myRepeat.DataBind()
          myDataReader.Close()
          conn.Close()
       End If
    End Sub

    Public Sub myRepeat_ItemCommand _
                     (ByVal sender As Object, _
                      ByVal e As RepeaterCommandEventArgs)
       ausgabe.innerHTML = "Anruf bei dieser Nummer: " _
               & CType(e.CommandSource, Button).Text
    End Sub

    </script>
    <html><head><title>
    Repeater-Steuerelement mit ItemCommand-Ereignis
    </title></head>
    <body>
    <h3>Repeater-Steuerelement mit ItemCommand-Ereignis
    </h3>
    <form runat="server">
    <asp:repeater id="myRepeat" runat="server"
                  OnItemCommand="myRepeat_ItemCommand" >

       <HeaderTemplate>
          Versandfirmen mit Tel-Nr.: <table border="0">
       </HeaderTemplate>

       <ItemTemplate>
          <tr><td><%# DataBinder.Eval _
                          (Container.DataItem, "Firma") %>
          <td><asp:Button runat="server" Text=
    '<%# DataBinder.Eval(Container.DataItem, "Telefon") %>'
               />
       </ItemTemplate>

       <FooterTemplate>
          </table>
       </FooterTemplate>

    </asp:repeater>
    <p runat="server" id="ausgabe" />
    </form></body></html>
Hier klicken, um das Bild zu Vergrößern Abbildung 12.21 Jeder Eintrag erhält eine eigene Schaltfläche. db_22.aspx verwendet für die Vorlagen des Repeater-Steuerelements eine Tabellenstruktur. Die Schaltfläche in der zweiten Spalte wird mit Hilfe eines Button-Steuerelements erzeugt. Für die Beschriftung der Schaltfläche wird der bereits bekannte Datenbindungsausdruck verwendet:
    <asp:Button runat="server" Text=
    '<%# DataBinder.Eval(Container.DataItem, "Telefon") %>'  />
Beachten Sie die unterschiedlichen Anführungszeichen. Dem Attribut Text wird sein Wert mit Hilfe einfacher Anführungszeichen zugewiesen. Auf diese Weise können innerhalb des Datenbindungsausdrucks doppelte Anführungszeichen verwendet werden. Im Repeater-Element wird mit OnItemCommand="myRepeat_ItemCommand" die zugehörige Prozedur für die Ereignisbehandlung zugewiesen. Diese Prozedur gibt die gewählte Nummer unter der Tabelle aus.
    Public Sub myRepeat_ItemCommand _
                     (ByVal sender As Object, _
                      ByVal e As RepeaterCommandEventArgs)
       ausgabe.innerHTML = "Anruf bei dieser Nummer: " _
               & CType(e.CommandSource, Button).Text
    End Sub
Der Ereignisprozedur myRepeat_ItemCommand wird ein Objekt vom Typ RepeaterCommandEventArgs als Parameter übergeben. Über dessen Eigenschaft CommandSource ist die auslösende Schaltfläche verfügbar. Nach der Konvertierung in ein Button-Objekt mit CType(e.CommandSource, Button) kann die Prozedur auf die Text-Eigenschaft zugreifen. Eine weitere Änderung betrifft die Page-Deklaration und die Prozedur Page_Load. db_21.aspx hat die Option EnableViewState="false" verwendet, um den generierten HTML-Code so knapp wie möglich zu halten. Das war möglich, weil der Inhalt der Seite bei jedem Laden erneut generiert wurde. db_22.aspx erstellt den Inhalt der Seite aber nur beim erstmaligen Laden, denn die Seite verwendet die If-Abfrage If Not IsPostBack ... Bei einem Postback sollen die Inhalte statt dessen aus dem Viewstate genommen werden, so dass jetzt in der Page-Deklaration die Option EnableViewState="true" verwendet werden muss. Würde diese Option auf false gelassen, wäre die Seite bei einem Postback leer.
<< zurück | <top> | vor >>
Zum Katalog
Einstieg in ASP.NET bestellen
Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen? Ihre Meinung

.NET-Bibliothek
| Einstieg in VB.NET
| VB.NET
| Einstieg in C#
| Visual C#
| VB.NET und Datenbanken

Empfehlung
| Einstieg in XML

Shopping
Versandkostenfrei bestellen in Deutschland und Österreich Info

MyGalileo
Der Service für registrierte Leser: Info

Copyright © Galileo Press GmbH 2003
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

[Galileo Computing]
Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de