Galileo Computing < openbook >
Galileo Computing - Programming the Net
Galileo Computing - Programming the Net


Einstieg in ASP.NET von Matthias Lohrer
Einstieg in ASP.NET
gp Kapitel 12 ASP.NET und Datenbanken
  gp 12.1 Auf Datenbanken zugreifen – ein Crashkurs
    gp 12.1.1 Eine Tabelle im Browser anzeigen
    gp 12.1.2 Über den Browser einen Datensatz hinzufügen
  gp 12.2 Wie ADO.NET funktioniert – ein Überblick
  gp 12.3 Die Verbindung zur Datenbank herstellen
    gp 12.3.1 OleDbConnection
    gp 12.3.2 SqlConnection
  gp 12.4 Daten lesen mit SqlCommand und OleDbCommand
    gp 12.4.1 ExecuteReader
    gp 12.4.2 ExecuteNonQuery und die Parameters-Collection
    gp 12.4.3 ExecuteScalar
  gp 12.5 SqlDataReader und OleDbDataReader
    gp 12.5.1 Ein Reader-Objekt an ein Steuerelement binden
    gp 12.5.2 Ein Reader-Objekt an ein Listensteuerelement binden
    gp 12.5.3 Ein Reader-Objekt zeilenweise auswerten
  gp 12.6 Die DataSet-Klasse
    gp 12.6.1 Das Zusammenspiel von Command, Adapter und DataSet
    gp 12.6.2 Mehrere Tabellen in ein DataSet-Objekt einlesen
    gp 12.6.3 Auf einzelne Zeilen, Spalten und Tabellen eines DataSet-Objekts gezielt zugreifen
    gp 12.6.4 Relationen zwischen Tabellen festlegen
  gp 12.7 DataViews verwenden
    gp 12.7.1 Tabellen sortieren
    gp 12.7.2 Tabellen nach Inhalten filtern
    gp 12.7.3 Nach dem Zeilenstatus filtern
    gp 12.7.4 In Tabellen suchen
  gp 12.8 Mit ASP.NET Daten bearbeiten
  gp 12.9 Daten bearbeiten mit dem Command-Objekt
  gp 12.10 In-Place-Editing mit dem DataGrid-Steuerelement
    gp 12.10.1 Die EditItemIndex-Eigenschaft
    gp 12.10.2 Das asp:DataGrid-Tag anpassen
    gp 12.10.3 OnEditCommand: Daten bearbeiten
    gp 12.10.4 OnCancelCommand: Die Bearbeitung abbrechen
    gp 12.10.5 OnUpdateCommand: Die Änderungen sichern
    gp 12.10.6 Das Repeater-Steuerelement verwenden
    gp 12.10.7 Die Ereignisse des Repeater-Steuerelements auswerten
  gp 12.11 Das DataList-Steuerelement
    gp 12.11.1 In-Place-Editing mit dem DataList-Steuerelement


Galileo Computing

12.11 Das DataList-Steuerelement  downtop

Das DataList-Steuerelement ist dem Repeater-Steuerelement sehr ähnlich. Die Ähnlichkeit geht so weit, dass Sie beispielsweise in db_21.aspx den Namen Repeater einfach gegen DataList austauschen können. Anschließend erhalten Sie exakt das gleiche Ergebnis wie bei der Verwendung des Repeater-Steuerelements.

Das DataList bietet folgende zusätzliche Merkmale:

gp  Ähnlich wie das DataGrid-Steuerelement ermöglicht auch das DataList-Element das In-Place-Editing. Dafür steht die Vorlage EditItemTemplate zur Verfügung.
gp  Einträge können selektiert werden. Die Vorlage SelectedItemTemplate definiert das Aussehen eines selektierten Eintrags.
gp  Für die einzelnen Templates können Stileigenschaften definiert werden. Dazu dienen die Eigenschaften AlternatingItemStyle, EditItemStyle, FooterStyle, HeaderStyle, ItemStyle, SelectedItemStyle und SeparatorStyle.
gp  Mit ShowFooter und ShowHeader können Sie den Kopf- und den Fußbereich gezielt ein- und ausblenden.
gp  Mit der Eigenschaft RepeatColumns legen Sie die Anzahl der Spalten fest, in denen die Einträge dargestellt werden sollen. RepeatDirection definiert, ob diese Spalten von links nach rechts oder von oben nach unten aufgefüllt werden. RepeatLayout legt fest, ob die Darstellung mit Hilfe einer Tabelle erfolgt oder fließend umbricht.

Galileo Computing

12.11.1 In-Place-Editing mit dem DataList-Steuerelement  toptop

db_23.aspx realisiert die Möglichkeit des In-Place-Editings.

<!-- db_23.aspx --> 
<%@ Page Language="VB" Debug="True" Strict="True" 
         EnableViewstate="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script runat="server">
Dim connStr As String="Provider=Microsoft.Jet." _
    & "OLEDB.4.0;Data Source=" _
    & "C:\ASPdotNETBuch\Listings\Nordwind.mdb;"
 
Sub Page_Load (ByVal Sender As Object, _
               ByVal E As EventArgs)
   If not IsPostBack Then
      Datenlesen()
   End If               
End Sub
               
Sub Datenlesen()
   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()
   myDataList.DataSource = myDataReader
   myDataList.DataBind()
   myDataReader.Close()
   conn.Close()               
End Sub
Function executeSQL (ByVal inSQL As String) As Integer
   Dim conn As New OleDbConnection(connStr)
   conn.Open()
   Dim cmd As New OleDbCommand(inSQL, conn)
   Return cmd.ExecuteNonQuery()
   conn.Close()   
End Function

Public Sub OnUpdate(ByVal source As Object, _
           ByVal e As DataListCommandEventArgs)
   Dim telNeu, firmenID, sql As String
   telNeu = _
     CType(e.Item.FindControl("txtTel"), TextBox).Text
   firmenID = _
     CStr(myDataList.DataKeys(e.Item.ItemIndex)) 
   sql ="Update Versandfirmen SET Telefon='" _
        & telNeu _
        & "' WHERE [Firmen-Nr] = " & firmenID  
   ' Testweise das SQL-Statement ausgeben
   ausgabe.innerHTML = sql
   executeSQL(sql)
   myDataList.EditItemIndex = -1
   System.Threading.Thread.Sleep (500)
   Datenlesen()
End Sub

Public Sub OnDelete(ByVal source As Object, _
           ByVal e As DataListCommandEventArgs)
   Dim firmenID, sql As String
   firmenID = _
          CStr(myDataList.DataKeys(e.Item.ItemIndex))
   sql = "DELETE From Versandfirmen " _ 
         & "WHERE [Firmen-Nr]=" _
         & firmenID
   ' Testweise das SQL-Statement ausgeben
   ausgabe.innerHTML = sql
   executeSQL(sql)
   myDataList.EditItemIndex = -1
   System.Threading.Thread.Sleep (500)   
   Datenlesen()   
End Sub
Public Sub OnEdit(ByVal source As Object, _
           ByVal e As DataListCommandEventArgs)
   myDataList.EditItemIndex = e.Item.ItemIndex
   Datenlesen()
End Sub

Public Sub OnCancel(ByVal source As Object, _
           ByVal e As DataListCommandEventArgs)
   myDataList.EditItemIndex = -1
   Datenlesen()
End Sub 

</script>
<html><head><title>DataList-Steuerelement</title>
</head><body>
<h3>DataList-Steuerelement</h3>
<form runat="server">
<asp:DataList id="myDataList" runat="server" 
     HeaderStyle-Font-Bold
     DataKeyField="Firmen-Nr"
     OnEditCommand="OnEdit"
     OnDeleteCommand="OnDelete"
     OnCancelCommand="OnCancel"
     OnUpdateCommand="OnUpdate" >
   
   <HeaderTemplate>
      Versandfirmen mit Tel-Nr.:
   </HeaderTemplate>
   
   <ItemTemplate>
      <%# DataBinder.Eval _
                      (Container.DataItem, "Firma") %>
      <td><%# DataBinder.Eval _
                     (Container.DataItem, "Telefon")%>
      <td><asp:Button CommandName="Edit" 
               runat="server" 
               Text ="Tel.-Nr. ändern" />                     
   </ItemTemplate>

   <EditItemTemplate>
      <%# DataBinder.Eval _
                      (Container.DataItem, "Firma") %>
      <td><asp:TextBox runat="server" id="txtTel"
               Text='<%# DataBinder.Eval _
                    (Container.DataItem, "Telefon") %>'
           />
      <td>
      <asp:Button CommandName="Update" 
                      Text="Speichern"
                      runat="server"
                      id="btnUpdate" />      
      <asp:Button CommandName="Cancel" 
                      Text="Abbrechen"
                      runat="server"
                      id="btnCancel" />      
      <asp:Button CommandName="Delete" 
                      Text="Datensatz löschen"
                      runat="server"
                      id="btnDelete" />      
   </EditItemTemplate>
            
</asp:DataList>
<p id="ausgabe" runat="server" />
</form></body></html>

Abbildung 12.22 zeigt die unterschiedlichen Darstellungen im Browser. Im HTML-Abschnitt von db_23.aspx deklariert das DataList-Element drei Templates, und zwar das HeaderTemplate, das ItemTemplate und das EditItemTemplate.

HeaderTemplate

Die Eigenschaft RepeatLayout wird nicht eigens festgelegt, so dass automatisch die Tabellenform gewählt wird. Der HeaderTemplate definiert beispielsweise lediglich den Text Versandfirmen mit Tel-Nr.:. Wenn man im Browser einen Blick auf den generierten Quellcode wirft, erkennt man, dass ASP.NET folgenden Code generiert hat:

<table id="myDataList" cellspacing="0" border="0" style="border-collapse:collapse;">
<tr><td style="font-weight:bold;">
Versandfirmen mit Tel-Nr.:
</td></tr>

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 12.22 Auch das DataList-Steuerelement ermöglicht das In-Place-Editing.

Offenkundig kümmert sich das Steuerelement selbst um die benötigten Tabellenelemente, so dass es nicht nötig ist, Tags wie <tr> und <td> selbst zu setzen.

Das Tag für die Kopfzeile enthält die Stileigenschaft <td style="font-weight:bold;">. Hier findet sich das Attribut HeaderStyle-Font-Bold wieder, das innerhalb des DataList-Elements gesetzt wurde.

ItemTemplate

In der Deklaration von ItemTemplate fällt auf, dass hier nun doch das <td>-Tag verwendet wird. Davon ausgenommen ist die erste Spalte für die Firma, die kein <td>-Tag erhält. Für die erste Spalte generiert das DataList-Element automatisch das benötigte td-Element.

Die hier gewählte Verwendung ist gewissermaßen untypisch. Das DataList-Element ist so gedacht, dass die Einträge alle innerhalb einer Zelle erscheinen sollen. Die Ausweitung auf mehrere Spalten ist eher die Domäne des DataGrid-Steuerelements.

Für die dritte Spalte fügt das ItemTemplate eine Edit-Schaltfläche hinzu. Mit Hilfe dieser Schaltfläche kann der Anwender die Telefon-Nummer ändern. Die Zuordnung zu einer Prozedur erfolgt im DataList-Element selbst mit dem Attribut OnEditCommand="OnEdit". Der Skriptteil von db_23.aspx enthält die Prozedur OnEdit().

EditItemTemplate

Auch EditItemTemplate definiert die Inhalte für drei Spalten. Die erste Spalte ist identisch mit dem Inhalt bei ItemTemplate. Hier wird lediglich der Inhalt der Spalte Firma ausgegeben.

Die zweite Spalte erhält ein TextBox-Element. Hier kann der Anwender die Telefonnummer bearbeiten. Über das Text-Attribut wird die aktuelle Nummer in das Textfeld geschrieben. Außerdem erhält das Textfeld die id="txtTel". Dieses id-Attribut wird später die OnUpdate-Prozedur wieder aufgreifen.

Die dritte Spalte erhält drei Schaltflächen. Sie ermöglichen das Speichern der Änderungen, das Abbrechen des Vorgangs und den Vorgang Datensatz löschen. Die Schaltfläche auf der Hauptseite heißt Tel-Nr. ändern. Daher ist es nicht in sich stimmig, dass hier auch die Möglichkeit zum Löschen des Datensatzes geboten wird. Diese Option habe ich hier lediglich ergänzt, um das Prinzip zu demonstrieren.

Die drei Button-Elemente definieren jeweils das CommandName-Attribut. Im DataList-Element erfolgt die Zuordnung zu einer konkreten Prozedur, z. B. OnUpdateCommand="OnUpdate".

Im DataList-Element wird außerdem der Wert DataKeyField="Firmen-Nr" gesetzt. Das DataKeyField-Attribut legt das Schlüsselfeld fest, über das auf die zugrunde liegende Tabelle zugegriffen werden kann.

Page_Load()

Beim ersten Öffnen der Seite soll die Prozedur Datenlesen() ausgeführt werden, sonst passiert nichts.

Datenlesen()

Die Prozedur Datenlesen() liest die Daten in das DataList-Steuerelement ein und führt die Datenbindung aus. Datenlesen() wird von Page_Load() aufgerufen und von den vier Prozeduren, die die Daten bearbeiten. Der Wert von e.Item.EditItemIndex steuert jeweils, welcher Datensatz bearbeitet werden soll. Wenn dieser Wert auf -1 steht, wird kein Datensatz bearbeitet.

executeSQL()

executeSQL() führt einen SQL-Befehl aus, der keine Query enthält, sondern einen UPDATE- oder einen DELETE-Befehl. Die Prozeduren OnUpdate() und OnDelete() greifen auf diese Hilfsprozedur zurück.

OnUpdate()

OnUpdate()baut den SQL-Befehl für die Datenbankaktualisierung zusammen. Der SQL-Befehl wird für Debugging-Zwecke unter dem DataList-Steuerelement ausgegeben und mit Hilfe von executeSQL() ausgeführt.

Dieser SQL-Befehl hat beispielsweise diese Form:

Update Versandfirmen SET Telefon='8876753' WHERE [Firmen-Nr] = 8

Der SQL-Befehl enthält zwei variable Bestandteile: die Telefonnummer, die der Anwender eingegeben hat, und die Firmen-Nr, die für diese Tabelle das Schlüsselfeld darstellt.

Die Eingabe des Anwenders ermitteln Sie mit dem Ausdruck e.Item.FindControl("txtTel"), der das Steuerelement mit der id txtTel ausfindig macht. Anschließend kann dieses Objekt in ein Objekt vom Typ TextBox konvertiert und die Text-Eigenschaft ausgelesen werden.

Die Firmen-Nr des Datensatzes, der bearbeitet wird, erreichen Sie über die DataKeys-Eigenschaft des DataList-Steuerelements. Mit myDataList.DataKeys(e.Item.ItemIndex) ermitteln Sie den gesuchten Wert. Ermöglicht wird dieses Verfahren durch das Attribut DataKeyField="Firmen-Nr" des DataList-Elements.

Damit haben Sie alle benötigten Bestandteile für den SQL-Befehl ermittelt. Der Befehl wird mit Hilfe der Prozedur executeSQL() ausgeführt. Anschließend wird die EditItemIndex-Eigenschaft des DataList-Objekts auf -1 gesetzt und die Daten werden erneut mit Datenlesen() ermittelt. Damit wird die Tabelle neu aufgebaut.


Achtung   Bleibt noch der Aufruf System.Threading.Thread.Sleep (500) zu erklären. Wenn Sie diesen Befehl auskommentieren und die Prozedur ausführen, können Sie eine merkwürdige Beobachtung machen. Die Änderung wird in der Datenbank zwar korrekt ausgeführt. Die Änderung wird aber nach dem Anklicken von Speichern nicht im Browser angezeigt. Erst bei einem Reload werden die Daten korrekt ausgelesen.

Der Grund dafür ist darin zu suchen, dass ASP.NET die Daten ausliest, noch bevor die Änderungen in der Datenbank gespeichert werden konnten. Daraus resultiert die Idee, vor dem Aufruf der Prozedur Datenlesen() eine künstliche Pause von 500 Millisekunden einzulegen. Diese Zeit reicht aus, damit die Änderungen in der Access-Datenbank auch wirklich ankommen. Die Daten werden mit dieser kleinen Pause korrekt angezeigt.

OnDelete()

OnDelete() arbeitet ähnlich wie OnUpdate(). Der SQL-Befehl wird zusammengesetzt und mit executeSQL() ausgeführt. Anschließend wird ebenfalls eine künstliche Pause eingelegt und die Tabelle wird neu aufgebaut.

OnEdit()

OnEdit() wird aufgerufen, wenn der Anwender die Schaltfläche Tel.-Nr. ändern anklickt. Die Methode setzt die EditItemIndex-Eigenschaft auf den Wert des Datensatzes, den der Anwender angeklickt hat, und veranlasst anschließend mit Datenlesen() den erneuten Aufbau der Tabelle.

OnCancel()

Die Funktionsweise von OnCancel() entspricht der Arbeitsweise von OnEdit(). Die EditItemIndex-Eigenschaft wird auf -1 gesetzt. Das bedeutet, dass keine Zeile bearbeitet werden soll. Mit dieser Einstellung wird der erneute Aufbau der Tabelle veranlasst.

  

Einstieg in VB.NET

VB.NET

Einstieg in C#

Visual C#

VB.NET und Datenbanken

Einstieg in XML




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