J'ai vu de nombreuses questions identiques ou similaires dans les forums : Comment placer des cases à cocher, des zones de texte, etc. dans chaque ligne de mon DataGrid ? Comment mettre à jour leurs valeurs ? La réponse est assez simple et dans cet article je vais vous montrer comment procéder.
Nous savons tous que DataGrid est un outil très puissant. D'après mon expérience, plus de 90 % du temps, le DataGrid est utilisé pour afficher des données et éventuellement les modifier une ligne à la fois. Parfois, vous devrez peut-être modifier plusieurs lignes, voire toutes les données à la fois. Un exemple pratique serait dans une application qui vend des articles en ligne, où les clients pourraient vouloir modifier un ou plusieurs articles de leur panier à la fois, en cliquant sur les cases à cocher pour supprimer les articles dont ils ne veulent pas.
Concept
Dans cet exemple, j'ai écrit un simple WebForm pour gérer une liste de contacts stockée en XML. L'exigence est très simple : avoir la possibilité d'ajouter de nouveaux contacts, de modifier/supprimer des contacts existants. Les utilisateurs peuvent modifier ou supprimer plusieurs contacts à la fois, et je leur permets également de trier la grille de données par colonnes de leur choix.
Mes exemples sont écrits en C#. Si vous préférez la version VB de ces codes, le code est disponible dans les deux formats dans le fichier à télécharger.
Le fichier de données XML dans l'
exempleContacts.xml
est très simple et intuitif.Comme c'est très simple, je n'ai pas créé de plan.
<?xml version="1.0" standalone="oui"?>
<Contacts>
<Contact>
<Email>[email protected]</Email>
<Premier>Jean</Premier>
<LastName>Biche</LastName>
</Contact>
<Contact>
<Email>[email protected]</Email>
<Premier>Jeanne</PremierNom>
<LastName>Biche</LastName>
</Contact>
</Contacts>
ContactList.aspx
La configuration d'un WebForm est très simple. J'ai placé un nouveau DataGrid dans mon formulaire et je l'ai configuré pour avoir 4 colonnes, la première colonne contenant des cases à cocher pour supprimer des contacts. Vous remarquerez que la principale chose que j'ai faite ici est de créer chaque colonne en tant que colonne modèle (TemplateColumn). Cela me permet de placer des objets textbox et checkbox dans le modèle de données (ItemTemplate). C'est une astuce pour afficher autre chose que du texte dans chaque ligne de la grille. De plus, vous remarquerez que j'utilise un FooterTemplate pour rendre la création de nouveaux contacts facile et intuitive.
J'ai également inclus un LinkButton pour enregistrer les modifications et suppressions effectuées par l'utilisateur. Mais il ne sert pas à ajouter de nouveaux contacts. L'opération d'ajout de nouveaux contacts est complétée par le bouton de lien (LinkButton) dans le modèle de pied de page de la dernière colonne.
<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" Largeur="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>
<Colonnes>
<asp:TemplateColumn SortExpression="FirstName" HeaderText="First Name">
<Modèle d'élément>
<asp:TextBox id=First runat="server" width="109px" Text='<%# DataBinder.Eval(Container, "DataItem.FirstName") %>'>
</asp:TextBox>
</ItemTemplate>
<Modèle de pied de page>
<asp:TextBox id="NewFirst" runat="server" width="109px"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="LastName" HeaderText="Last Name">
<Modèle d'élément>
<asp:TextBox id=Last runat="server" width="109px" Text='<%# DataBinder.Eval(Container, "DataItem.LastName") %>'>
</asp:TextBox>
</ItemTemplate>
<Modèle de pied de page>
<asp:TextBox id="NewLast" runat="server" width="109px"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="Email" HeaderText="Email">
<Modèle d'élément>
<asp:TextBox id=Email runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Email") %>'>
</asp:TextBox>
</ItemTemplate>
<Modèle de pied de page>
<asp:TextBox id="NewEmail" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Supprimer le contact">
<ItemStyle HorizontalAlign="Centre"></ItemStyle>
<Modèle d'élément>
<asp:CheckBox Runat="server" ID="chkDelete"></asp:CheckBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Centre"></FooterStyle>
<Modèle de pied de page>
<asp:LinkButton Runat="server" Text="Add" CommandName="Add" ID="Linkbutton1" NAME="Linkbutton1"></asp:LinkButton>
</FooterTemplate>
</asp:TemplateColumn>
</Colonnes>
</asp:grille de données>
ContactList.cs
Après avoir choisi d'utiliser un fichier XML pour accéder aux données, j'ai décidé d'utiliser un DataSet pour y accéder. Étant donné que l'objet DataSet possède les méthodes ReadXml et WriteXml, il s'agit d'un choix très raisonnable. La première étape consiste à lire les données en XML. Comme vous pouvez le voir sur le code, j'ai créé un membre pour gérer le tri des données.
DataSet privé _dsContacts ;
chaîne privée _sSort ;
privé void Page_Load (expéditeur de l'objet, System.EventArgs e)
{
//Charger le fichier XML.
_dsContacts = nouveau DataSet();
_dsContacts.ReadXml(Server.MapPath("Contacts.xml"));
DataColumn[] dcPk = {_dsContacts.Tables["Contact"].Columns["Email"]};
_dsContacts.Tables["Contact"].PrimaryKey = dcPk;
si (!Page.IsPostBack )
{
// S'il est chargé pour la première fois, lie les données.
LierContacts();
_sSort = "Prénom" ;
}
autre
{
// Sinon, lit l'état de tri à partir de l'état d'affichage.
_sSort = (string)ViewState["Tri"];
}
}
Dans la deuxième étape, j'ai créé une méthode pour lier les données à la grille, qui comprenait une logique de tri des données et des méthodes de lecture des données à partir du disque.
vide privé BindContacts()
{
//Enregistre l'état de tri pour afficher l'état.
ViewState["Sort"] = _sSort;
// Lie la grille à la vue des données triées.
DataView dv = new DataView(_dsContacts.Tables["Contact"]);
dv.Tri = _sSort ;
dgContacts.DataSource = dv;
dgContacts.DataBind();
}
privé vide SaveContacts()
{
_dsContacts.WriteXml(Server.MapPath("Contacts.xml"));
}
L'événement ItemCommand est utilisé pour gérer l'ajout de nouveaux contacts à la liste. Remarque : j'ai vérifié si le paramètre CommandName est Add. Il sert à gérer la valeur de retour du bouton de lien (LinkButton) dans le modèle de pied de page (FooterTemplate) de la dernière colonne de la grille de la page ASPX.
private void dgContacts_ItemCommand (source de l'objet, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//Ajouter de nouvelles données à l'ensemble de données. Ici, j'utilise un tableau pour améliorer l'efficacité du traitement.
if (e.CommandName == "Ajouter")
{
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
();
}
LierContacts();
}
J'ai ignoré le code SortCommand car il existe de nombreux autres documents qui traitent du tri de manière très détaillée. Si vous téléchargez le code source de cet exemple, il est inclus.
Enfin, j'ai déplacé l'événement click (onClick) du bouton lien (LinkButton) sur le formulaire ici. Ici, je parcoure les éléments de données du DataGrid pour effectuer toutes les opérations de suppression et de mise à jour nécessaires.
private void btnUpdate_Click (expéditeur de l'objet, System.EventArgs e)
{
// Parcourez chaque élément de données.
foreach (DataGridItem dans dgContacts.Items)
{
// Assurez-vous qu'il s'agit d'un élément de données et non du haut ou du bas de la page.
if (di.ItemType == ListItemType.Item || di.ItemType == ListItemType.AlternatingItem)
{
// Récupère la ligne actuelle après l'exécution de l'opération de mise à jour ou de suppression.
DataRow dr = _dsContacts.Tables["Contact"].Rows.Find(dgContacts.DataKeys[di.ItemIndex]);
// Vérifiez si une ligne doit être supprimée.
if (((CheckBox)di.FindControl("chkDelete")).Checked)
{
_dsContacts.Tables["Contact"].Rows.Remove(dr);//Supprimer la ligne spécifiée
}
autre
{
//Mise à jour la ligne de données.
dr["Email"] = ((TextBox)di.FindControl("Email").Text;
dr["FirstName"] = ((TextBox)di.FindControl("First").Text;
dr["LastName"] = ((TextBox)di.FindControl("Last").Text;
}
}
}
// Enregistrez-le s'il y a des modifications.
si (_dsContacts.HasChanges())
{
Enregistrer les contacts ();
}
BindContacts();//Liaison
}
Conclusion
Je peux facilement trouver les cellules (Cells) de chaque DataGridItem dans le contrôle grâce à la position du contrôle. Il existe plusieurs façons d'accomplir cela, et je suis sûr que vous pouvez trouver une meilleure façon d'accomplir cette tâche. Comme vous pouvez le constater, modifier l’intégralité de la grille de données en même temps est très simple. La même méthode peut également être utilisée pour les grilles paginées avec de légères modifications