Insertion d’un nouvel enregistrement à partir du pied de page d’un contrôle GridView (C#)
par Scott Mitchell
Bien que le contrôle GridView ne fournisse pas de prise en charge intégrée pour l’insertion d’un nouvel enregistrement de données, ce tutoriel montre comment augmenter GridView pour inclure une interface d’insertion.
Introduction
Comme indiqué dans le didacticiel Vue d’ensemble de l’insertion, de la mise à jour et de la suppression de données, les contrôles GridView, DetailsView et FormView Web incluent chacun des fonctionnalités intégrées de modification des données. Lorsqu’ils sont utilisés avec des contrôles de source de données déclaratifs, ces trois contrôles Web peuvent être rapidement et facilement configurés pour modifier des données, et dans des scénarios sans avoir à écrire une seule ligne de code. Malheureusement, seuls les contrôles DetailsView et FormView fournissent des fonctionnalités intégrées d’insertion, de modification et de suppression. GridView offre uniquement la prise en charge de la modification et de la suppression. Toutefois, avec un peu de graisse de coude, nous pouvons augmenter le GridView pour inclure une interface d’insertion.
En ajoutant des fonctionnalités d’insertion à GridView, nous sommes chargés de décider de la façon dont les nouveaux enregistrements seront ajoutés, de créer l’interface d’insertion et d’écrire le code pour insérer le nouvel enregistrement. Dans ce tutoriel, nous allons examiner l’ajout de l’interface d’insertion à la ligne de pied de page de GridView (voir la figure 1). La cellule de pied de page de chaque colonne inclut l’élément d’interface utilisateur de collecte de données approprié (un TextBox pour le nom du produit, un DropDownList pour le fournisseur, etc.). Nous avons également besoin d’une colonne pour un bouton Ajouter qui, lorsqu’on clique dessus, provoque une publication et insère un nouvel enregistrement dans la Products
table à l’aide des valeurs fournies dans la ligne de pied de page.
Figure 1 : La ligne de pied de page fournit une interface pour l’ajout de nouveaux produits (cliquer pour afficher l’image en taille réelle)
Étape 1 : Affichage des informations sur le produit dans un GridView
Avant de nous préoccuper de la création de l’interface d’insertion dans le pied de page de GridView, nous allons d’abord nous concentrer sur l’ajout d’un GridView à la page qui répertorie les produits dans la base de données. Commencez par ouvrir la InsertThroughFooter.aspx
page dans le EnhancedGridView
dossier et faites glisser un GridView de la boîte à outils vers le Designer, en définissant la propriété de ID
GridView sur Products
. Ensuite, utilisez la balise active de GridView pour la lier à un nouvel ObjetDataSource nommé ProductsDataSource
.
Figure 2 : Créer un objetDataSource nommé ProductsDataSource
(cliquer pour afficher l’image en taille réelle)
Configurez ObjectDataSource pour utiliser la méthode de la ProductsBLL
classe s GetProducts()
pour récupérer des informations sur le produit. Pour ce tutoriel, nous allons nous concentrer uniquement sur l’ajout de fonctionnalités d’insertion et ne pas vous soucier de la modification et de la suppression. Par conséquent, assurez-vous que la liste déroulante de l’onglet INSERT est définie AddProduct()
sur et que les listes déroulantes des onglets UPDATE et DELETE sont définies sur (Aucun).
Figure 3 : Mapper la AddProduct
méthode à la méthode ObjectDataSource Insert()
(cliquez pour afficher l’image en taille réelle)
Figure 4 : Définissez les onglets UPDATE et DELETE Drop-Down Listes sur (Aucun) (Cliquez pour afficher l’image en taille réelle)
Après avoir terminé l’Assistant Configuration de la source de données d’ObjectDataSource, Visual Studio ajoute automatiquement des champs à GridView pour chacun des champs de données correspondants. Pour l’instant, laissez tous les champs ajoutés par Visual Studio. Plus loin dans ce tutoriel, nous allons revenir et supprimer certains des champs dont les valeurs n’ont pas besoin d’être spécifiées lors de l’ajout d’un nouvel enregistrement.
Étant donné qu’il y a près de 80 produits dans la base de données, un utilisateur doit faire défiler jusqu’au bas de la page web pour ajouter un nouvel enregistrement. Par conséquent, nous allons activer la pagination pour rendre l’interface d’insertion plus visible et plus accessible. Pour activer la pagination, case activée simplement la case Activer la pagination à partir de la balise active gridView.
À ce stade, le balisage déclaratif gridView et ObjectDataSource doit ressembler à ce qui suit :
<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
AllowPaging="True" EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True"
SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="QuantityPerUnit" HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock"
SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder"
SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel" HeaderText="ReorderLevel"
SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="SupplierName"
ReadOnly="True" SortExpression="SupplierName" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
<InsertParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="quantityPerUnit" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="unitsInStock" Type="Int16" />
<asp:Parameter Name="unitsOnOrder" Type="Int16" />
<asp:Parameter Name="reorderLevel" Type="Int16" />
<asp:Parameter Name="discontinued" Type="Boolean" />
</InsertParameters>
</asp:ObjectDataSource>
Figure 5 : Tous les champs de données de produit sont affichés dans un objet GridView paginé (cliquez pour afficher l’image en taille réelle)
Étape 2 : Ajout d’une ligne de pied de page
En plus de ses lignes d’en-tête et de données, gridView inclut une ligne de pied de page. Les lignes d’en-tête et de pied de page sont affichées en fonction des valeurs des propriétés et ShowFooter
des ShowHeader
propriétés GridView. Pour afficher la ligne de pied de page, définissez simplement la propriété sur ShowFooter
true
. Comme l’illustre la figure 6, la définition de la ShowFooter
propriété sur true
ajoute une ligne de pied de page à la grille.
Figure 6 : Pour afficher la ligne de pied de page, définissez sur ShowFooter
True
(Cliquez pour afficher l’image en taille réelle)
Notez que la ligne de pied de page a une couleur d’arrière-plan rouge foncé. Cela est dû au thème DataWebControls que nous avons créé et appliqué à toutes les pages dans le didacticiel Affichage des données avec ObjectDataSource . Plus précisément, le GridView.skin
fichier configure la FooterStyle
propriété de sorte qu’utilise la FooterStyle
classe CSS. La FooterStyle
classe est définie dans Styles.css
comme suit :
.FooterStyle
{
background-color: #a33;
color: White;
text-align: right;
}
Notes
Nous avons exploré l’utilisation de la ligne de pied de page GridView dans les tutoriels précédents. Si nécessaire, reportez-vous au didacticiel Affichage des informations récapitulatives du pied de page de GridView pour une actualisation.
Après avoir défini la ShowFooter
propriété sur true
, prenez un moment pour afficher la sortie dans un navigateur. Actuellement, la ligne de pied de page ne contient aucun texte ni aucun contrôle Web. À l’étape 3, nous allons modifier le pied de page de chaque champ GridView afin qu’il inclue l’interface d’insertion appropriée.
Figure 7 : La ligne de pied de page vide s’affiche au-dessus des contrôles de l’interface de pagination (cliquer pour afficher l’image en taille réelle)
Étape 3 : Personnalisation de la ligne de pied de page
Dans le didacticiel Utilisation de TemplateFields dans le contrôle GridView , nous avons vu comment personnaliser considérablement l’affichage d’une colonne GridView particulière à l’aide de TemplateFields (par opposition à BoundFields ou CheckBoxFields) ; Dans Personnalisation de l’interface de modification des données , nous avons examiné l’utilisation de TemplateFields pour personnaliser l’interface d’édition dans un GridView. Rappelez-vous qu’un TemplateField est composé d’un certain nombre de modèles qui définissent la combinaison de balisage, de contrôles Web et de syntaxe de liaison de données utilisée pour certains types de lignes. , ItemTemplate
par exemple, spécifie le modèle utilisé pour les lignes en lecture seule, tandis que définit EditItemTemplate
le modèle pour la ligne modifiable.
Avec et ItemTemplate
EditItemTemplate
, le TemplateField inclut également un FooterTemplate
qui spécifie le contenu de la ligne de pied de page. Par conséquent, nous pouvons ajouter les contrôles Web nécessaires pour chaque interface d’insertion de champ dans le FooterTemplate
. Pour commencer, convertissez tous les champs dans GridView en TemplateFields. Pour ce faire, cliquez sur le lien Modifier les colonnes dans la balise active de GridView, sélectionnez chaque champ dans le coin inférieur gauche et cliquez sur le lien Convertir ce champ en un champ TemplateField.
Figure 8 : Convertir chaque champ en champ de modèle
Si vous cliquez sur Convertir ce champ en champ TemplateField, le type de champ actuel devient un champ TemplateField équivalent. Par exemple, chaque objet BoundField est remplacé par un objet TemplateField par un ItemTemplate
qui contient un Label qui affiche le champ de données correspondant et un EditItemTemplate
qui affiche le champ de données dans un TextBox. L’objet ProductName
BoundField a été converti en balisage TemplateField suivant :
<asp:TemplateField HeaderText="ProductName" SortExpression="ProductName">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"
Text='<%# Bind("ProductName") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server"
Text='<%# Bind("ProductName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
De même, le Discontinued
Champ CheckBox a été converti en un TemplateField dont ItemTemplate
et EditItemTemplate
contiennent un contrôle Web CheckBox (avec le ItemTemplate
CheckBox désactivé). L’objet BoundField en lecture seule ProductID
a été converti en templateField avec un contrôle Label dans et ItemTemplate
EditItemTemplate
. En bref, la conversion d’un champ GridView existant en templateField est un moyen rapide et simple de basculer vers le TemplateField plus personnalisable sans perdre aucune des fonctionnalités de champ existantes.
Étant donné que le GridView avec lequel nous travaillons ne prend pas en charge la modification, n’hésitez pas à supprimer de EditItemTemplate
chaque TemplateField, en laissant uniquement le ItemTemplate
. Après cela, votre balisage déclaratif gridView doit ressembler à ce qui suit :
<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
AllowPaging="True" EnableViewState="False" ShowFooter="True">
<Columns>
<asp:TemplateField HeaderText="ProductID" InsertVisible="False"
SortExpression="ProductID">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("ProductID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ProductName" SortExpression="ProductName">
<ItemTemplate>
<asp:Label ID="Label2" runat="server"
Text='<%# Bind("ProductName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="SupplierID" SortExpression="SupplierID">
<ItemTemplate>
<asp:Label ID="Label3" runat="server"
Text='<%# Bind("SupplierID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="CategoryID" SortExpression="CategoryID">
<ItemTemplate>
<asp:Label ID="Label4" runat="server"
Text='<%# Bind("CategoryID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit">
<ItemTemplate>
<asp:Label ID="Label5" runat="server"
Text='<%# Bind("QuantityPerUnit") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitPrice" SortExpression="UnitPrice">
<ItemTemplate>
<asp:Label ID="Label6" runat="server"
Text='<%# Bind("UnitPrice") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitsInStock"
SortExpression="UnitsInStock">
<ItemTemplate>
<asp:Label ID="Label7" runat="server"
Text='<%# Bind("UnitsInStock") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitsOnOrder"
SortExpression="UnitsOnOrder">
<ItemTemplate>
<asp:Label ID="Label8" runat="server"
Text='<%# Bind("UnitsOnOrder") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ReorderLevel"
SortExpression="ReorderLevel">
<ItemTemplate>
<asp:Label ID="Label9" runat="server"
Text='<%# Bind("ReorderLevel") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Discontinued"
SortExpression="Discontinued">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server"
Checked='<%# Bind("Discontinued") %>' Enabled="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="CategoryName"
SortExpression="CategoryName">
<ItemTemplate>
<asp:Label ID="Label10" runat="server"
Text='<%# Bind("CategoryName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="SupplierName"
SortExpression="SupplierName">
<ItemTemplate>
<asp:Label ID="Label11" runat="server"
Text='<%# Bind("SupplierName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Maintenant que chaque champ GridView a été converti en templateField, nous pouvons entrer l’interface d’insertion appropriée dans chaque champ de FooterTemplate
. Certains champs n’auront pas d’interface d’insertion (ProductID
par instance) ; d’autres varient dans les contrôles Web utilisés pour collecter les informations du nouveau produit.
Pour créer l’interface d’édition, choisissez le lien Modifier les modèles à partir de la balise active gridView. Ensuite, dans la liste déroulante, sélectionnez les champs appropriés FooterTemplate
et faites glisser le contrôle approprié de la boîte à outils vers le Designer.
Figure 9 : Ajouter l’interface d’insertion appropriée à chaque champ FooterTemplate
(cliquer pour afficher l’image en taille réelle)
La liste à puces suivante énumère les champs GridView, en spécifiant l’interface d’insertion à ajouter :
ProductID
Aucun.ProductName
ajoutez un contrôle TextBox et définissez sonID
surNewProductName
. Ajoutez également un contrôle RequiredFieldValidator pour vous assurer que l’utilisateur entre une valeur pour le nom du nouveau produit.SupplierID
Aucun.CategoryID
Aucun.QuantityPerUnit
ajoutez un TextBox, en affectantID
la valeur àNewQuantityPerUnit
.UnitPrice
ajoutez un TextBox nomméNewUnitPrice
et un CompareValidator qui garantit que la valeur entrée est une valeur monétaire supérieure ou égale à zéro.UnitsInStock
utilisez un Contrôle TextBox dontID
la valeur est définie surNewUnitsInStock
. Incluez un CompareValidator qui garantit que la valeur entrée est une valeur entière supérieure ou égale à zéro.UnitsOnOrder
utilisez un Contrôle TextBox dontID
la valeur est définie surNewUnitsOnOrder
. Incluez un CompareValidator qui garantit que la valeur entrée est une valeur entière supérieure ou égale à zéro.ReorderLevel
utilisez un Contrôle TextBox dontID
la valeur est définie surNewReorderLevel
. Incluez un CompareValidator qui garantit que la valeur entrée est une valeur entière supérieure ou égale à zéro.Discontinued
ajoutez un contrôle CheckBox, en affectantID
la valeur àNewDiscontinued
.CategoryName
ajoutez un DropDownList et définissez sonID
surNewCategoryID
. Liez-le à un nouvel ObjetDataSource nomméCategoriesDataSource
et configurez-le pour qu’il utilise laCategoriesBLL
méthode de classe sGetCategories()
. Faites en charge que les s deListItem
DropDownList affichent leCategoryName
champ de données, en utilisant leCategoryID
champ de données comme valeurs.SupplierName
ajoutez un DropDownList et définissez sonID
surNewSupplierID
. Liez-le à un nouvel ObjetDataSource nomméSuppliersDataSource
et configurez-le pour qu’il utilise laSuppliersBLL
méthode de classe sGetSuppliers()
. Faites en charge que les s deListItem
DropDownList affichent leCompanyName
champ de données, en utilisant leSupplierID
champ de données comme valeurs.
Pour chacun des contrôles de validation, effacez la ForeColor
propriété afin que la couleur de premier plan blanche de la FooterStyle
classe CSS soit utilisée à la place du rouge par défaut. Utilisez également la ErrorMessage
propriété pour une description détaillée, mais définissez la Text
propriété sur un astérisque. Pour empêcher le texte du contrôle de validation d’entraîner un encapsulation de l’interface d’insertion sur deux lignes, définissez la FooterStyle
propriété s Wrap
sur false pour chacun des s qui utilisent un contrôle de FooterTemplate
validation. Enfin, ajoutez un contrôle ValidationSummary sous gridView et définissez sa ShowMessageBox
propriété sur true
et sa ShowSummary
propriété false
sur .
Lors de l’ajout d’un nouveau produit, nous devons fournir et CategoryID
SupplierID
. Ces informations sont capturées par le biais des listes déroulantes dans les cellules du pied de page pour les CategoryName
champs et SupplierName
. J’ai choisi d’utiliser ces champs par opposition à CategoryID
et SupplierID
TemplateFields, car dans les lignes de données de la grille, l’utilisateur est probablement plus intéressé à voir les noms de catégorie et de fournisseur que leurs valeurs d’ID. Étant donné que les CategoryID
valeurs et SupplierID
sont désormais capturées dans les CategoryName
interfaces d’insertion de champ et SupplierName
, nous pouvons supprimer les CategoryID
champs et SupplierID
de l’objet GridView.
De même, le ProductID
n’est pas utilisé lors de l’ajout d’un nouveau produit, de sorte que templateField ProductID
peut également être supprimé. Toutefois, laissez le ProductID
champ dans la grille. En plus des contrôles TextBoxes, DropDownLists, CheckBoxes et validation qui composent l’interface d’insertion, nous aurons également besoin d’un bouton Ajouter qui, une fois cliqué, exécute la logique pour ajouter le nouveau produit à la base de données. À l’étape 4, nous allons inclure un bouton Ajouter dans l’interface d’insertion dans templateField ProductID
s FooterTemplate
.
N’hésitez pas à améliorer l’apparence des différents champs GridView. Par exemple, vous souhaiterez peut-être mettre en forme les UnitPrice
valeurs en tant que devise, aligner à droite les UnitsInStock
champs , UnitsOnOrder
et et ReorderLevel
mettre à jour les HeaderText
valeurs des Champs de modèles.
Après avoir créé la quantité d’insertion d’interfaces dans les FooterTemplate
s, la suppression SupplierID
CategoryID
des et templateFields et l’amélioration de l’esthétique de la grille par la mise en forme et l’alignement des TemplateFields, le balisage déclaratif de votre GridView doit ressembler à ce qui suit :
<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
AllowPaging="True" EnableViewState="False" ShowFooter="True">
<Columns>
<asp:TemplateField HeaderText="ProductID" InsertVisible="False"
SortExpression="ProductID">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("ProductID") %>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Product" SortExpression="ProductName">
<ItemTemplate>
<asp:Label ID="Label2" runat="server"
Text='<%# Bind("ProductName") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="NewProductName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
runat="server" ControlToValidate="NewProductName"
Display="Dynamic" ForeColor="
ErrorMessage="You must enter a name for the new product.">
* </asp:RequiredFieldValidator>
</FooterTemplate>
<FooterStyle Wrap="False" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
<ItemTemplate>
<asp:Label ID="Label10" runat="server"
Text='<%# Bind("CategoryName") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="NewCategoryID" runat="server"
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName" DataValueField="CategoryID">
</asp:DropDownList>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Supplier" SortExpression="SupplierName">
<ItemTemplate>
<asp:Label ID="Label11" runat="server"
Text='<%# Bind("SupplierName") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="NewSupplierID" runat="server"
DataSourceID="SuppliersDataSource"
DataTextField="CompanyName" DataValueField="SupplierID">
</asp:DropDownList><asp:ObjectDataSource ID="SuppliersDataSource"
runat="server" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Qty/Unit" SortExpression="QuantityPerUnit">
<ItemTemplate>
<asp:Label ID="Label5" runat="server"
Text='<%# Bind("QuantityPerUnit") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="NewQuantityPerUnit" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price" SortExpression="UnitPrice">
<ItemTemplate>
<asp:Label ID="Label6" runat="server"
Text='<%# Bind("UnitPrice", "{0:c}") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
$<asp:TextBox ID="NewUnitPrice" runat="server" Columns="8" />
<asp:CompareValidator ID="CompareValidator1" runat="server"
ControlToValidate="NewUnitPrice"
ErrorMessage="You must enter a valid currency value greater than
or equal to 0.00. Do not include the currency symbol."
ForeColor="" Operator="GreaterThanEqual" Type="Currency"
ValueToCompare="0" Display="Dynamic">
* </asp:CompareValidator>
</FooterTemplate>
<ItemStyle HorizontalAlign="Right" />
<FooterStyle Wrap="False" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Units In Stock"
SortExpression="Units In Stock">
<ItemTemplate>
<asp:Label ID="Label7" runat="server"
Text='<%# Bind("UnitsInStock") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="NewUnitsInStock" runat="server" Columns="5" />
<asp:CompareValidator ID="CompareValidator2" runat="server"
ControlToValidate="NewUnitsInStock" Display="Dynamic"
ErrorMessage="You must enter a valid numeric value for units
in stock that's greater than or equal to zero."
ForeColor="" Operator="GreaterThanEqual" Type="Integer"
ValueToCompare="0">*</asp:CompareValidator>
</FooterTemplate>
<ItemStyle HorizontalAlign="Right" />
<FooterStyle Wrap="False" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Units On Order" SortExpression="UnitsOnOrder">
<ItemTemplate>
<asp:Label ID="Label8" runat="server"
Text='<%# Bind("UnitsOnOrder") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="NewUnitsOnOrder" runat="server" Columns="5" />
<asp:CompareValidator ID="CompareValidator3" runat="server"
ControlToValidate="NewUnitsOnOrder" Display="Dynamic"
ErrorMessage="You must enter a valid numeric value for units on
order that's greater than or equal to zero."
ForeColor="" Operator="GreaterThanEqual" Type="Integer"
ValueToCompare="0">*</asp:CompareValidator>
</FooterTemplate>
<ItemStyle HorizontalAlign="Right" />
<FooterStyle Wrap="False" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Reorder Level" SortExpression="ReorderLevel">
<ItemTemplate>
<asp:Label ID="Label9" runat="server"
Text='<%# Bind("ReorderLevel") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="NewReorderLevel" runat="server" Columns="5" />
<asp:CompareValidator ID="CompareValidator4" runat="server"
ControlToValidate="NewReorderLevel" Display="Dynamic"
ErrorMessage="You must enter a valid numeric value for reorder
level that's greater than or equal to zero."
ForeColor="" Operator="GreaterThanEqual" Type="Integer"
ValueToCompare="0">*</asp:CompareValidator>
</FooterTemplate>
<ItemStyle HorizontalAlign="Right" />
<FooterStyle Wrap="False" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server"
Checked='<%# Bind("Discontinued") %>' Enabled="false" />
</ItemTemplate>
<FooterTemplate>
<asp:CheckBox ID="NewDiscontinued" runat="server" />
</FooterTemplate>
<ItemStyle HorizontalAlign="Center" />
<FooterStyle HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
Lorsqu’elle est consultée via un navigateur, la ligne de pied de page GridView inclut désormais l’interface d’insertion terminée (voir figure 10). À ce stade, l’interface d’insertion n’inclut pas de moyen permettant à l’utilisateur d’indiquer qu’il a entré les données pour le nouveau produit et qu’il souhaite insérer un nouvel enregistrement dans la base de données. En outre, nous n’avons pas encore abordé la façon dont les données entrées dans le pied de page se traduisent en un nouvel enregistrement dans la Products
base de données. À l’étape 4, nous allons voir comment inclure un bouton Ajouter à l’interface d’insertion et comment exécuter du code sur la publication en cas de clic. L’étape 5 montre comment insérer un nouvel enregistrement à l’aide des données du pied de page.
Figure 10 : Le pied de page GridView fournit une interface pour l’ajout d’un nouvel enregistrement (cliquez pour afficher une image de taille réelle)
Étape 4 : Inclusion d’un bouton Ajouter dans l’interface d’insertion
Nous devons inclure un bouton Ajouter quelque part dans l’interface d’insertion, car l’interface d’insertion de ligne de pied de page ne dispose pas actuellement des moyens permettant à l’utilisateur d’indiquer qu’il a terminé d’entrer les informations du nouveau produit. Cela peut être placé dans l’un des s existants FooterTemplate
ou nous pourrions ajouter une nouvelle colonne à la grille à cet effet. Pour ce tutoriel, placez le bouton Ajouter dans templateField ProductID
s FooterTemplate
.
Dans le Designer, cliquez sur le lien Modifier les modèles dans la balise active GridView, puis choisissez les ProductID
champs dans FooterTemplate
la liste déroulante. Ajoutez un contrôle Web Button (ou un LinkButton ou ImageButton, si vous préférez) au modèle, en définissant son ID AddProduct
sur , sur CommandName
Insérer et sa Text
propriété sur Ajouter, comme illustré dans la figure 11.
Figure 11 : Placez le bouton Ajouter dans templateField ProductID
s FooterTemplate
(cliquez pour afficher l’image en taille réelle)
Une fois que vous avez inclus le bouton Ajouter, testez la page dans un navigateur. Notez que lorsque vous cliquez sur le bouton Ajouter avec des données non valides dans l’interface d’insertion, la publication est court-circuitée et le contrôle ValidationSummary indique les données non valides (voir figure 12). Une fois les données appropriées entrées, le fait de cliquer sur le bouton Ajouter entraîne une publication. Toutefois, aucun enregistrement n’est ajouté à la base de données. Nous devrons écrire un peu de code pour effectuer l’insertion.
Figure 12 : La publication du bouton Ajouter est court-circuitée s’il existe des données non valides dans l’interface d’insertion (cliquer pour afficher l’image en taille réelle)
Notes
Les contrôles de validation dans l’interface d’insertion n’ont pas été attribués à un groupe de validation. Cela fonctionne correctement tant que l’interface d’insertion est le seul ensemble de contrôles de validation sur la page. Toutefois, si d’autres contrôles de validation figurent sur la page (tels que les contrôles de validation dans l’interface d’édition de grille), les contrôles de validation de l’interface d’insertion et les propriétés des ValidationGroup
boutons Ajouter doivent se voir attribuer la même valeur afin d’associer ces contrôles à un groupe de validation particulier. Pour plus d’informations sur le partitionnement des contrôles de validation et des boutons d’une page en groupes de validation, consultez Dissecting the Validation Controls in ASP.NET 2.0 .
Étape 5 : Insertion d’un nouvel enregistrement dans laProducts
table
Lors de l’utilisation des fonctionnalités d’édition intégrées de GridView, GridView gère automatiquement tout le travail nécessaire à l’exécution de la mise à jour. En particulier, lorsque vous cliquez sur le bouton Mettre à jour, il copie les valeurs entrées à partir de l’interface d’édition vers les paramètres de la collection ObjectDataSource UpdateParameters
et lance la mise à jour en appelant la méthode ObjectDataSource.Update()
Étant donné que GridView ne fournit pas de telles fonctionnalités intégrées pour l’insertion, nous devons implémenter du code qui appelle la méthode s Insert()
ObjectDataSource et copie les valeurs de l’interface d’insertion vers la collection ObjectDataSource InsertParameters
.
Cette logique d’insertion doit être exécutée une fois que vous avez cliqué sur le bouton Ajouter. Comme indiqué dans le tutoriel Ajout et réponse à des boutons d’un didacticiel GridView , chaque fois qu’un bouton, linkbutton ou imagebutton dans un GridView est cliqué, l’événement GridView se déclenche lors de RowCommand
la publication. Cet événement se déclenche si le Bouton, LinkButton ou ImageButton a été ajouté explicitement, par exemple le bouton Ajouter dans la ligne du pied de page ou s’il a été automatiquement ajouté par GridView (par exemple, linkButtons en haut de chaque colonne lorsque l’option Activer le tri est sélectionnée, ou les LinkButtons dans l’interface de pagination lorsque l’option Activer la pagination est sélectionnée).
Par conséquent, pour répondre à l’utilisateur qui clique sur le bouton Ajouter, nous devons créer un gestionnaire d’événements pour l’événement GridView.RowCommand
Étant donné que cet événement se déclenche chaque fois qu’un bouton, linkbutton ou imageButton dans GridView est cliqué, il est essentiel que nous ne poursuivions la logique d’insertion que si la CommandName
propriété passée dans le gestionnaire d’événements correspond à la CommandName
valeur du bouton Ajouter ( Insérer ). De plus, nous ne devons continuer que si les contrôles de validation signalent des données valides. Pour ce faire, créez un gestionnaire d’événements pour l’événement RowCommand
avec le code suivant :
protected void Products_RowCommand(object sender, GridViewCommandEventArgs e)
{
// Insert data if the CommandName == "Insert"
// and the validation controls indicate valid data...
if (e.CommandName == "Insert" && Page.IsValid)
{
// TODO: Insert new record...
}
}
Notes
Vous vous demandez peut-être pourquoi le gestionnaire d’événements s’embête à vérifier la Page.IsValid
propriété. Après tout, la publication ne sera-t-elle pas supprimée si des données non valides sont fournies dans l’interface d’insertion ? Cette hypothèse est correcte tant que l’utilisateur n’a pas désactivé JavaScript ou a pris des mesures pour contourner la logique de validation côté client. En bref, il ne faut jamais s’appuyer strictement sur la validation côté client ; une case activée côté serveur pour la validité doit toujours être effectuée avant d’utiliser les données.
À l’étape 1, nous avons créé l’ObjetDataSource ProductsDataSource
de telle sorte que sa Insert()
méthode soit mappée à la méthode de classe ProductsBLL
s AddProduct
. Pour insérer le nouvel enregistrement dans la Products
table, nous pouvons simplement appeler la méthode s Insert()
ObjectDataSource :
protected void Products_RowCommand(object sender, GridViewCommandEventArgs e)
{
// Insert data if the CommandName == "Insert"
// and the validation controls indicate valid data...
if (e.CommandName == "Insert" && Page.IsValid)
{
// Insert new record
ProductsDataSource.Insert();
}
}
Maintenant que la Insert()
méthode a été appelée, il ne reste plus qu’à copier les valeurs de l’interface d’insertion vers les paramètres passés à la ProductsBLL
méthode class s AddProduct
. Comme nous l’avons vu dans le didacticiel Examen des événements associés à l’insertion, à la mise à jour et à la suppression , cela peut être effectué via l’événement Inserting
ObjectDataSource. Dans le Inserting
cas où nous devons référencer par programmation les contrôles à partir de la Products
ligne de pied de page GridView et affecter leurs valeurs à la e.InputParameters
collection. Si l’utilisateur omet une valeur telle que la ReorderLevel
zone de texte vide, nous devons spécifier que la valeur insérée dans la base de données doit être NULL
. Étant donné que la AddProducts
méthode accepte les types nullables pour les champs de base de données nullables, utilisez simplement un type nullable et définissez sa valeur sur null
dans le cas où l’entrée utilisateur est omise.
protected void ProductsDataSource_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
// Programmatically reference Web controls in the inserting interface...
TextBox NewProductName =
(TextBox)Products.FooterRow.FindControl("NewProductName");
DropDownList NewCategoryID =
(DropDownList)Products.FooterRow.FindControl("NewCategoryID");
DropDownList NewSupplierID =
(DropDownList)Products.FooterRow.FindControl("NewSupplierID");
TextBox NewQuantityPerUnit =
(TextBox)Products.FooterRow.FindControl("NewQuantityPerUnit");
TextBox NewUnitPrice =
(TextBox)Products.FooterRow.FindControl("NewUnitPrice");
TextBox NewUnitsInStock =
(TextBox)Products.FooterRow.FindControl("NewUnitsInStock");
TextBox NewUnitsOnOrder =
(TextBox)Products.FooterRow.FindControl("NewUnitsOnOrder");
TextBox NewReorderLevel =
(TextBox)Products.FooterRow.FindControl("NewReorderLevel");
CheckBox NewDiscontinued =
(CheckBox)Products.FooterRow.FindControl("NewDiscontinued");
// Set the ObjectDataSource's InsertParameters values...
e.InputParameters["productName"] = NewProductName.Text;
e.InputParameters["supplierID"] =
Convert.ToInt32(NewSupplierID.SelectedValue);
e.InputParameters["categoryID"] =
Convert.ToInt32(NewCategoryID.SelectedValue);
string quantityPerUnit = null;
if (!string.IsNullOrEmpty(NewQuantityPerUnit.Text))
quantityPerUnit = NewQuantityPerUnit.Text;
e.InputParameters["quantityPerUnit"] = quantityPerUnit;
decimal? unitPrice = null;
if (!string.IsNullOrEmpty(NewUnitPrice.Text))
unitPrice = Convert.ToDecimal(NewUnitPrice.Text);
e.InputParameters["unitPrice"] = unitPrice;
short? unitsInStock = null;
if (!string.IsNullOrEmpty(NewUnitsInStock.Text))
unitsInStock = Convert.ToInt16(NewUnitsInStock.Text);
e.InputParameters["unitsInStock"] = unitsInStock;
short? unitsOnOrder = null;
if (!string.IsNullOrEmpty(NewUnitsOnOrder.Text))
unitsOnOrder = Convert.ToInt16(NewUnitsOnOrder.Text);
e.InputParameters["unitsOnOrder"] = unitsOnOrder;
short? reorderLevel = null;
if (!string.IsNullOrEmpty(NewReorderLevel.Text))
reorderLevel = Convert.ToInt16(NewReorderLevel.Text);
e.InputParameters["reorderLevel"] = reorderLevel;
e.InputParameters["discontinued"] = NewDiscontinued.Checked;
}
Une fois le Inserting
gestionnaire d’événements terminé, de nouveaux enregistrements peuvent être ajoutés à la table de base Products
de données via la ligne de pied de page GridView. Essayez d’ajouter plusieurs nouveaux produits.
Amélioration et personnalisation de l’opération d’ajout
Actuellement, cliquer sur le bouton Ajouter ajoute un nouvel enregistrement à la table de base de données, mais ne fournit aucun commentaire visuel indiquant que l’enregistrement a été correctement ajouté. Dans l’idéal, un contrôle Label Web ou une zone d’alerte côté client informerait l’utilisateur que son insertion s’est terminée avec succès. Je laisse cela comme un exercice pour le lecteur.
Le GridView utilisé dans ce tutoriel n’applique aucun ordre de tri aux produits répertoriés et ne permet pas à l’utilisateur final de trier les données. Par conséquent, les enregistrements sont classés tels qu’ils se trouvent dans la base de données par leur champ de clé primaire. Étant donné que chaque nouvel enregistrement a une ProductID
valeur supérieure au dernier, chaque fois qu’un nouveau produit est ajouté, il est ajouté à la fin de la grille. Par conséquent, vous pouvez envoyer automatiquement l’utilisateur à la dernière page de GridView après avoir ajouté un nouvel enregistrement. Pour ce faire, ajoutez la ligne de code suivante après l’appel à ProductsDataSource.Insert()
dans le RowCommand
gestionnaire d’événements pour indiquer que l’utilisateur doit être envoyé à la dernière page après la liaison des données à GridView :
// Indicate that the user needs to be sent to the last page
SendUserToLastPage = true;
SendUserToLastPage
est une variable booléenne au niveau de la page à laquelle est initialement attribuée une valeur de false
. Dans le gestionnaire d’événements DataBound
GridView, si SendUserToLastPage
est false, la PageIndex
propriété est mise à jour pour envoyer l’utilisateur à la dernière page.
protected void Products_DataBound(object sender, EventArgs e)
{
// Send user to last page of data, if needed
if (SendUserToLastPage)
Products.PageIndex = Products.PageCount - 1;
}
La raison pour laquelle la PageIndex
propriété est définie dans le DataBound
gestionnaire d’événements (par opposition au gestionnaire d’événements) est due au RowCommand
fait que lorsque le RowCommand
gestionnaire d’événements se déclenche, nous n’avons pas encore ajouté le nouvel enregistrement à la table de base Products
de données. Par conséquent, dans le RowCommand
gestionnaire d’événements, l’index de la dernière page (PageCount - 1
) représente le dernier index de page avant l’ajout du nouveau produit. Pour la majorité des produits ajoutés, l’index de la dernière page est le même après l’ajout du nouveau produit. Toutefois, lorsque le produit ajouté aboutit à un nouvel index de dernière page, si nous mettons à jour incorrectement le PageIndex
dans le RowCommand
gestionnaire d’événements, nous sommes dirigés vers l’avant-dernière page (l’index de la dernière page avant l’ajout du nouveau produit) par opposition au nouvel index de dernière page. Étant donné que le DataBound
gestionnaire d’événements se déclenche après que le nouveau produit a été ajouté et que les données rebondissent dans la grille, en définissant la PageIndex
propriété, nous savons que nous obtenons l’index de dernière page correct.
Enfin, le GridView utilisé dans ce tutoriel est assez large en raison du nombre de champs qui doivent être collectés pour l’ajout d’un nouveau produit. En raison de cette largeur, une disposition verticale de DetailsView peut être préférable. La largeur globale du GridView peut être réduite en collectant moins d’entrées. Nous n’avons peut-être pas besoin de collecter les UnitsOnOrder
champs , UnitsInStock
et ReorderLevel
lors de l’ajout d’un nouveau produit, auquel cas ces champs peuvent être supprimés de GridView.
Pour ajuster les données collectées, nous pouvons utiliser l’une des deux approches suivantes :
- Continuez à utiliser la
AddProduct
méthode qui attend des valeurs pour lesUnitsOnOrder
champs ,UnitsInStock
etReorderLevel
. Dans leInserting
gestionnaire d’événements, fournissez des valeurs par défaut codées en dur à utiliser pour ces entrées qui ont été supprimées de l’interface d’insertion. - Créez une surcharge de la
AddProduct
méthode dans laProductsBLL
classe qui n’accepte pas d’entrées pour lesUnitsOnOrder
champs ,UnitsInStock
etReorderLevel
. Ensuite, dans la page ASP.NET, configurez ObjectDataSource pour utiliser cette nouvelle surcharge.
L’une ou l’autre option fonctionnera également. Dans les didacticiels précédents, nous avons utilisé cette dernière option, créant plusieurs surcharges pour la ProductsBLL
méthode class s UpdateProduct
.
Résumé
GridView ne dispose pas des fonctionnalités d’insertion intégrées trouvées dans DetailsView et FormView, mais avec un peu d’effort, une interface d’insertion peut être ajoutée à la ligne de pied de page. Pour afficher la ligne de pied de page dans un GridView, définissez simplement sa ShowFooter
propriété sur true
. Le contenu de la ligne de pied de page peut être personnalisé pour chaque champ en convertissant le champ en templateField et en ajoutant l’interface d’insertion à .FooterTemplate
Comme nous l’avons vu dans ce tutoriel, peut FooterTemplate
contenir des boutons, des textboxes, des dropDownLists, des checkboxes, des contrôles de source de données pour remplir des contrôles Web pilotés par les données (tels que DropDownLists) et des contrôles de validation. En plus des contrôles permettant de collecter l’entrée de l’utilisateur, un bouton Ajouter, linkButton ou ImageButton est nécessaire.
Lorsque vous cliquez sur le bouton Ajouter, la méthode ObjectDataSource Insert()
est appelée pour démarrer le flux de travail d’insertion. ObjectDataSource appelle ensuite la méthode insert configurée (la ProductsBLL
méthode class s AddProduct
, dans ce didacticiel). Nous devons copier les valeurs de l’interface d’insertion de GridView dans la collection ObjectDataSource InsertParameters
avant d’appeler la méthode insert. Pour ce faire, référençant par programmation les contrôles Web de l’interface d’insertion dans le gestionnaire d’événements Inserting
ObjectDataSource.
Ce tutoriel complète notre présentation des techniques permettant d’améliorer l’apparence de GridView. L’ensemble suivant de tutoriels examine comment utiliser des données binaires telles que des images, des fichiers PDF, des documents Word, etc. ainsi que les contrôles web de données.
Bonne programmation !
À propos de l’auteur
Scott Mitchell, auteur de sept livres ASP/ASP.NET et fondateur de 4GuysFromRolla.com, travaille avec les technologies Web Microsoft depuis 1998. Scott travaille comme consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Il est accessible à l’adressemitchell@4GuysFromRolla.com . ou via son blog, qui se trouve à l’adresse http://ScottOnWriting.NET.
Remerciements spéciaux à
Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. La réviseure principale de ce tutoriel était Bernadette Leigh. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.