Ich habe in Foren viele gleiche oder ähnliche Fragen gesehen: Wie platziere ich Kontrollkästchen, Textfelder usw. in jeder Zeile meines DataGrid? Wie aktualisiere ich ihre Werte? Die Antwort ist ziemlich einfach und in diesem Artikel zeige ich Ihnen, wie es geht.
Wir alle wissen, dass DataGrid ein sehr leistungsfähiges Tool ist. Nach meiner Erfahrung wird das DataGrid in mehr als 90 % der Fälle dazu verwendet, Daten anzuzeigen und möglicherweise zeilenweise zu bearbeiten. Manchmal müssen Sie möglicherweise mehrere Zeilen oder sogar alle Daten auf einmal bearbeiten. Ein praktisches Beispiel wäre eine Anwendung zum Online-Verkauf von Artikeln, bei der Kunden möglicherweise einen oder mehrere Artikel in ihrem Warenkorb gleichzeitig ändern möchten, indem sie auf Kontrollkästchen klicken, um die Artikel zu entfernen, die sie nicht möchten.
Konzept
In diesem Beispiel habe ich ein einfaches WebForm geschrieben, um eine in XML gespeicherte Kontaktliste zu verwalten. Die Anforderung ist sehr einfach: Sie müssen die Möglichkeit haben, neue Kontakte hinzuzufügen und bestehende Kontakte zu bearbeiten/löschen. Benutzer können mehrere Kontakte gleichzeitig ändern oder löschen, und ich erlaube Benutzern auch, das Datenraster nach Spalten ihrer Wahl zu sortieren.
Meine Beispiele sind in C# geschrieben. Wenn Sie die VB-Version dieser Codes bevorzugen, ist der Code in beiden Formaten in der Download-Datei verfügbar.
Die XML-Datendatei im
Beispiel „Contacts.xml“
ist sehr einfach und intuitiv.Da es sehr einfach ist, habe ich keinen Plan erstellt.
<?xml version="1.0" standalone="yes"?>
<Kontakte>
<Kontakt>
<Email>[email protected]</Email>
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Kontakt>
<Kontakt>
<Email>[email protected]</Email>
<Vorname>Jane</Vorname>
<LastName>Doe</LastName>
</Kontakt>
</Contacts>
ContactList.aspx
Das Einrichten eines WebForms ist sehr einfach. Ich habe ein neues DataGrid in mein Formular eingefügt und es so eingerichtet, dass es vier Spalten hat, wobei die erste Spalte Kontrollkästchen zum Löschen von Kontakten enthält. Sie werden feststellen, dass ich hier hauptsächlich jede Spalte als Vorlagenspalte (TemplateColumn) erstellt habe. Dadurch kann ich Textfeld- und Kontrollkästchenobjekte in der Datenvorlage (ItemTemplate) platzieren. Dies ist ein Trick, um in jeder Zeile des Rasters etwas anderes als Text anzuzeigen. Darüber hinaus werden Sie feststellen, dass ich eine FooterTemplate verwende, um das Erstellen neuer Kontakte einfach und intuitiv zu gestalten.
Ich habe auch einen LinkButton eingefügt, um vom Benutzer vorgenommene Änderungen und Löschungen zu speichern. Es wird jedoch nicht zum Hinzufügen neuer Kontakte verwendet. Das Hinzufügen neuer Kontakte wird durch die Link-Schaltfläche (LinkButton) in der Fußzeilenvorlage der letzten Spalte abgeschlossen.
<asp:datagrid id="dgContacts" runat="server" ShowFooter="True" AllowSorting="True" Forefont color="Black" GridLines="None" CellPadding="2" Backfont color="LightGoldenrodYellow" BorderWidth="1px " Borderfont color="Tan" Width="499px" AutoGenerateColumns="False" DataKeyField="Email">
<SelectedItemStyle Forefont color="GhostWhite" Backfont color="DarkSlateBlue"></SelectedItemStyle>
<AlternatingItemStyle Backfont color="PaleGoldenrod"></AlternatingItemStyle>
<HeaderStyle Font-Bold="True" Backfont color="Tan"></HeaderStyle>
<FooterStyle Backfont color="Tan"></FooterStyle>
<Spalten>
<asp:TemplateColumn SortExpression="FirstName" HeaderText="First Name">
<ItemTemplate>
<asp:TextBox id=First runat="server" Width="109px" Text='<%# DataBinder.Eval(Container, "DataItem.FirstName") %>'>
</asp:TextBox>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id="NewFirst" runat="server" Breite="109px"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="LastName" HeaderText="Last Name">
<ItemTemplate>
<asp:TextBox id=Last runat="server" Width="109px" Text='<%# DataBinder.Eval(Container, "DataItem.LastName") %>'>
</asp:TextBox>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id="NewLast" runat="server" Breite="109px"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="Email" HeaderText="Email">
<ItemTemplate>
<asp:TextBox id=Email runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Email") %>'>
</asp:TextBox>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id="NewEmail" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Kontakt löschen">
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate>
<asp:CheckBox Runat="server" ID="chkDelete"></asp:CheckBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Center"></FooterStyle>
<FooterTemplate>
<asp:LinkButton Runat="server" Text="Add" CommandName="Add" ID="Linkbutton1" NAME="Linkbutton1"></asp:LinkButton>
</FooterTemplate>
</asp:TemplateColumn>
</Spalten>
</asp:datagrid>
ContactList.cs
Nachdem ich mich für die Verwendung einer XML-Datei für den Zugriff auf die Daten entschieden hatte, entschied ich mich für die Verwendung eines DataSets für den Zugriff. Da das DataSet-Objekt über die Methoden ReadXml und WriteXml verfügt, ist dies eine sehr vernünftige Wahl. Der erste Schritt besteht darin, die Daten in XML einzulesen. Wie Sie dem Code entnehmen können, habe ich ein Mitglied erstellt, das die Sortierung der Daten übernimmt.
privates DataSet _dsContacts;
private string _sSort;
private void Page_Load(object sender, System.EventArgs e)
{
//XML-Datei laden.
_dsContacts = new DataSet();
_dsContacts.ReadXml(Server.MapPath("Contacts.xml"));
DataColumn[] dcPk = {_dsContacts.Tables["Contact"].Columns["Email"]};
_dsContacts.Tables["Contact"].PrimaryKey = dcPk
;
{
// Wenn es zum ersten Mal geladen wird, Daten binden.
BindContacts();
_sSort = "Vorname";
}
anders
{
// Andernfalls den Sortierstatus aus dem Ansichtsstatus lesen.
_sSort = (string)ViewState["Sort"];
}
}
Im zweiten Schritt habe ich eine Methode zum Binden von Daten an das Raster erstellt, die Datensortierlogik und Methoden zum Lesen von Daten von der Festplatte umfasste.
private void BindContacts()
{
// Sortierstatus speichern, um den Status anzuzeigen.
ViewState["Sort"] = _sSort;
// Das Raster an die sortierte Datenansicht binden.
DataView dv = new DataView(_dsContacts.Tables["Contact"]);
dv.Sort = _sSort;
dgContacts.DataSource = dv;
dgContacts.DataBind();
}
private void SaveContacts()
{
_dsContacts.WriteXml(Server.MapPath("Contacts.xml"));
}
Das ItemCommand-Ereignis wird verwendet, um das Hinzufügen neuer Kontakte zur Liste zu verarbeiten. Hinweis: Ich habe überprüft, ob der CommandName-Parameter Add ist. Er dient dazu, den Rückgabewert der Link-Schaltfläche (LinkButton) in der Fußzeilenvorlage (FooterTemplate) der letzten Spalte des Rasters auf der ASPX-Seite zu verarbeiten.
private void dgContacts_ItemCommand(object source , System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//Füge neue Daten zum Datensatz hinzu. Hier verwende ich ein Array, um die Verarbeitungseffizienz zu verbessern.
if (e.CommandName == "Hinzufügen")
{
string[] sContact = {"", "", ""};
sContact[0] = ((TextBox)e.Item.FindControl("NewEmail")).Text;
sContact[1] = ((TextBox)e.Item.FindControl("NewFirst")).Text;
sContact[2] = ((TextBox)e.Item.FindControl("NewLast")).Text;
_dsContacts.Tables["Contact"].Rows.Add(sContacts
();
}
BindContacts();
}
Ich habe den SortCommand-Code übersprungen, da es viele andere Dokumente gibt, in denen das Sortieren ausführlich behandelt wird. Wenn Sie den Quellcode für dieses Beispiel herunterladen, ist er enthalten.
Schließlich habe ich das Klickereignis (onClick) des Link-Buttons (LinkButton) auf dem Formular hierher verschoben. Hier durchlaufe ich die Datenelemente im DataGrid, um alle erforderlichen Lösch- und Aktualisierungsvorgänge durchzuführen.
private void btnUpdate_Click(object sender, System.EventArgs e)
{
// Jedes Datenelement durchlaufen.
foreach (DataGridItem in dgContacts.Items)
{
// Stellen Sie sicher, dass es sich um ein Datenelement handelt und nicht oben oder unten auf der Seite.
if (di.ItemType == ListItemType.Item || di.ItemType == ListItemType.AlternatingItem)
{
// Aktuelle Zeile abrufen, nachdem der Aktualisierungs- oder Löschvorgang ausgeführt wurde.
DataRow dr = _dsContacts.Tables["Contact"].Rows.Find(dgContacts.DataKeys[di.ItemIndex]);
// Überprüfen Sie, ob eine Zeile gelöscht werden muss.
if (((CheckBox)di.FindControl("chkDelete")).Checked)
{
_dsContacts.Tables["Contact"].Rows.Remove(dr);//Löschen Sie die angegebene Zeile
}
anders
{
//Datenzeile aktualisieren.
dr["Email"] = ((TextBox)di.FindControl("Email")).Text;
dr["FirstName"] = ((TextBox)di.FindControl("First")).Text;
dr["LastName"] = ((TextBox)di.FindControl("Last")).Text;
}
}
}
//Speichern Sie es, wenn es Änderungen gibt.
if (_dsContacts.HasChanges())
{
SaveContacts();
}
BindContacts();//Binding
}
Fazit:
Ich kann die Zellen (Cells) jedes DataGridItem im Steuerelement anhand der Position des Steuerelements leicht finden. Es gibt mehrere Möglichkeiten, dies zu erreichen, und ich bin sicher, dass Sie einen besseren Weg finden werden, diese Aufgabe zu erfüllen. Wie Sie sehen, ist die Bearbeitung des gesamten Datenrasters auf einmal sehr einfach. Die gleiche Methode kann mit geringfügigen Modifikationen auch für paginierte Raster verwendet werden