Geschrieben von: Alexander Zeitler
Kategorie: .NET Fu
This printed page brought to you by AlphaSierraPapa
Das ASP.NET DataGrid ist das WebControl schlechthin, wenn es um die Anzeige und Bearbeitung tabellarischer Daten geht - wäre da nicht das leidige Problem mit den Unique-IDs der Datensätze: in der Praxis steht man immer wieder vor dem Problem, wie man die ID eines Datensatzes, der upgedatet werden soll, ermittelt, ohne die ID-Spalte im DataGrid anzuzeigen. Einen einfachen und eleganten Lösungsweg möchte ich heute aufzeigen.
Das heutige Ziel ist - zumindest im Ergebnis - im nachfolgenden Screenshot zu sehen:
Im ASP.NET DataGrid wird das Bearbeiten, Speichern, Abbrechen und Löschen von Datensätzen über die EventHandler "EditCommand", "UpdateCommand", "CancelCommand" und "DeleteCommand" gesteuert. Diese rufen die jeweiligen Methoden zur Ausführung der notwendigen Operation auf. Im Aufruf der jeweiligen Methode wird die Klasse DataGridCommandEventArgs übergeben.
In eben dieser Klasse stecken die Informationen zum jeweiligen Command. Die CommandName-Eigenschaft beinhaltet hierbei den Namen des jeweiligen Commands, z.B. "Edit".
Ein Blick in die Dokumentation der DataGridCommandEventArgs-Klasse zeigt, daß es eine weitere Eigenschaft namens "CommandArgument" gibt. Aus der Beschreibung dieser Eigenschaft:
"Das CommandArgument kann eine beliebige, vom Programmierer festgelegte Zeichenfolge enthalten. Die CommandArgument-Eigenschaft ergänzt die CommandName-Eigenschaft, indem sie das Angeben zusätzlicher Informationen für den Befehl ermöglicht."
Im Klartext: wenn wir unserem Befehl Parameter - z.B. die ID eines Datensatzes - für die Ausführung mitgeben möchten, so ist die Eigenschaft "CommandArgument" unsere erste Wahl.
Das einzige Problem, das sich jetzt noch stellt: wo übergeben wir diesen Parameter? In der MSDN werden wir unter dem Suchbegriff "CommandArgument" sehr schnell fündig und stoßen auf drei ASP.NET-Controls, die diese Eigenschaft besitzen:
Hiermit schließt sich der Kreis, denn eben diese drei Controls sind es, die auch unsere vorgenannten ItemCommands (Edit, Update etc.) im DataGrid auslösen können.
Der Weg ist somit also folgender:
Die Details zum Auslesen der Daten aus der Datenbank und das erstmalige Binden an das DataGrid spare ich mir hier und steige direkt in die Methode ItemDataBound ein, die aufgerufen wird, nachdem die Daten an das DataGrid gebunden wurden und uns somit für Punkt 1 unserer ToDo-Liste zur Verfügung stehen:
private void DataGrid1_ItemDataBound(object sender, DataGridItemEventArgs e) { if((e.Item.ItemType == ListItemType.AlternatingItem) || (e.Item.ItemType == ListItemType.Item)) { LinkButton lbtEdit = (LinkButton)e.Item.Cells[2].Controls[0]; lbtEdit.CommandArgument = ((DataRowView)e.Item.DataItem)["CustomerID"].ToString(); } }
Zunächst prüfen wir, ob es sich um ein DataGridItem vom ListItemType AlternatingItem oder Item handelt, denn nur diese beinhalten Daten aus der Datenbank und werden beim ersten Laden des DataGrids angezeigt.
Danach wird der LinkButton in der entsprechenden Spalte der aktuellen Zeile einem LinkButton-Objekt zugewiesen.
Dessen CommandArgument-Eigenschaft weisen wir nun den Wert des aktuellen DataItem zu, das wir in eine DataRowView casten und somit über den Spaltennamen der zugrundeliegenden DataTable unseres DataSets ansprechen können.
Damit ist Schritt 1 bereits vollständig abgehandelt - das DataGrid ist erzeugt und wir warten auf den Klick des Benutzers auf den Bearbeiten-Button unseres DataGrids.
Beim Klick auf besagten Button springen wir in die Methode "EditCommand", die sich wie folgt darstellt:
private void DataGrid1_EditCommand(object source, DataGridCommandEventArgs e) { DataGrid1.EditItemIndex = e.Item.ItemIndex; DataGrid1.SelectedIndex = e.Item.ItemIndex; DataGrid1.DataSource = this.ReadDataFromDB(); DataGrid1.DataBind(); LinkButton lbtUpdate = (LinkButton)this.DataGrid1.Items[e.Item.ItemIndex].Cells[2].Controls[0]; lbtUpdate.CommandArgument = e.CommandArgument.ToString(); }
Nach den bekannten Schritten zum Setzen von EditItem - und SelectedIndex und anschließendem DataBinding holen wir uns nun den LinkButton für das Update-Command. Zu beachten ist hierbei, daß wir nun den Button sowohl über den Spalten als auch über den Zeilenindex (= e.Item.ItemIndex) unseres DataGrids ansprechen müssen, da e.Item.Cells[2].Controls[0] den Button nicht zurückliefert. Schließlich weisen wir dem LinkButton das aktuelle CommandArgument - also unsere CustomerID - zu.
Nun fehlt uns lediglich noch die Methode zum Speichern der Daten beim Klick auf den Update-Button:
private void DataGrid1_UpdateCommand(object source, DataGridCommandEventArgs e) { string companyName = ((TextBox)e.Item.Cells[0].Controls[0]).Text; string address = ((TextBox)e.Item.Cells[1].Controls[0]).Text; string customerID = e.CommandArgument.ToString(); this.UpdateCustomer(customerID, companyName, address); DataGrid1.SelectedIndex = -1; DataGrid1.EditItemIndex = -1; DataGrid1.DataSource = this.ReadDataFromDB(); DataGrid1.DataBind(); }
Zunächst lesen wir die möglicherweise geänderten Daten aus den TextBoxen in lokale Variablen. Unsere CustomerID schreiben wir nun einfach vom aktuellen CommandArgument ebenfalls in eine lokale Variable, welche wir zusammen mit den beiden anderen an die UpdateCustomer-Methode übergeben. Diese kümmert sich erwartungsgemäß um das eigentliche Update der Daten in der Datenbank.
Abschließend versetzen wir unser DataGrid wieder in den Urzustand, indem wir die Indexe für das ausgewählte und das EditItem löschen und das DataGrid mit den aktualisierten Daten erneut binden.
Wie man sieht, hat sich Microsoft bei der Entwicklung des .NET Frameworks durchaus Gedanken gemacht und es lohnt sich, ab und zu einen Blick in dessen Dokumentation zu werfen. Der Verwendung des CommandArgument sind praktisch keine Grenzen gesetzt - denken Sie nur an das Löschen und Sortieren von Daten im DataGrid…
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20040929.zip
Das ASP.NET DataGrid selbst erweitern
http:/www.aspheute.com/artikel/20030909.htm
Einträge numerieren im DataGrid
http:/www.aspheute.com/artikel/20040317.htm
MouseOver-Effekte beim DataGrid
http:/www.aspheute.com/artikel/20040628.htm
Pager- und Footerzeilen des DataGrid erweitern
http:/www.aspheute.com/artikel/20040318.htm
Vergleich von DataGrid, DataList und Repeater-Control - was verwende ich wann?
http:/www.aspheute.com/artikel/20040303.htm
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.