Partager via


Insertion d’un nouvel enregistrement à partir du pied de page d’un contrôle GridView (C#)

par Scott Mitchell

Télécharger le PDF

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.

La ligne de pied de page fournit une interface pour l’ajout de nouveaux produits

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.

Créer un 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).

Mapper la méthode AddProduct à la méthode Insert() d’ObjectDataSource

Figure 3 : Mapper la AddProduct méthode à la méthode ObjectDataSource Insert() (cliquez pour afficher l’image en taille réelle)

Définissez les onglets UPDATE et DELETE Drop-Down Listes sur (Aucun)

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>

Tous les champs de données de produit sont affichés dans un GridView paginé

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)

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 ShowFootertrue. 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.

Pour afficher la ligne de pied de page, définissez ShowFooter sur True

Figure 6 : Pour afficher la ligne de pied de page, définissez sur ShowFooterTrue (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.

La ligne de pied de page vide est affichée au-dessus des contrôles de l’interface de pagination

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)

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. , ItemTemplatepar 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 ItemTemplateEditItemTemplate, 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.

Convertir chaque champ en champ de modèle

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 ItemTemplateEditItemTemplate. 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 (ProductIDpar 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.

Ajouter l’interface d’insertion appropriée au pied de page de chaque champTemplate

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 son ID sur NewProductName. 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 affectant ID 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 dont ID la valeur est définie sur NewUnitsInStock. 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 dont ID la valeur est définie sur NewUnitsOnOrder. 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 dont ID la valeur est définie sur NewReorderLevel. 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 affectant ID la valeur à NewDiscontinued.
  • CategoryName ajoutez un DropDownList et définissez son ID sur NewCategoryID. Liez-le à un nouvel ObjetDataSource nommé CategoriesDataSource et configurez-le pour qu’il utilise la CategoriesBLL méthode de classe s GetCategories() . Faites en charge que les s de ListItem DropDownList affichent le CategoryName champ de données, en utilisant le CategoryID champ de données comme valeurs.
  • SupplierName ajoutez un DropDownList et définissez son ID sur NewSupplierID. Liez-le à un nouvel ObjetDataSource nommé SuppliersDataSource et configurez-le pour qu’il utilise la SuppliersBLL méthode de classe s GetSuppliers() . Faites en charge que les s de ListItem DropDownList affichent le CompanyName champ de données, en utilisant le SupplierID 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é falsesur .

Lors de l’ajout d’un nouveau produit, nous devons fournir et CategoryIDSupplierID. 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 UnitsInStockchamps , UnitsOnOrderet 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 SupplierIDCategoryID 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.

Le pied de page GridView fournit une interface pour l’ajout d’un nouvel enregistrement

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 AddProductsur , sur CommandName Insérer et sa Text propriété sur Ajouter, comme illustré dans la figure 11.

Placez le bouton Ajouter dans le ProductID TemplateField s FooterTemplate

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.

La publication du bouton Ajouter est court-circuitée s’il existe des données non valides dans l’interface d’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 laProductstable

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 UnitsOnOrderchamps , UnitsInStocket 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 les UnitsOnOrderchamps , UnitsInStocket ReorderLevel . Dans le Inserting 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 la ProductsBLL classe qui n’accepte pas d’entrées pour les UnitsOnOrderchamps , UnitsInStocket ReorderLevel . 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.