Partager via


Vue d’ensemble de l’insertion, de la mise à jour et de la suppression de données (VB)

par Scott Mitchell

Télécharger le PDF

Dans ce tutoriel, nous allons voir comment mapper les méthodes Insert(), Update() et Delete() d’un ObjectDataSource aux méthodes des classes BLL, ainsi que comment configurer les contrôles GridView, DetailsView et FormView pour fournir des fonctionnalités de modification des données.

Introduction

Au cours des derniers didacticiels, nous avons examiné comment afficher des données dans une page ASP.NET à l’aide des contrôles GridView, DetailsView et FormView. Ces contrôles fonctionnent simplement avec les données fournies. En règle générale, ces contrôles accèdent aux données via l’utilisation d’un contrôle de source de données, tel que ObjectDataSource. Nous avons vu comment ObjectDataSource agit en tant que proxy entre la page ASP.NET et les données sous-jacentes. Lorsqu’un GridView doit afficher des données, il appelle sa méthode ObjectDataSource Select() , qui, à son tour, appelle une méthode de notre couche logique métier (BLL), qui appelle une méthode dans la table TableAdapter (DAL) appropriée, qui envoie à son tour une SELECT requête à la base de données Northwind.

Rappelez-vous que lorsque nous avons créé les TableAdapters dans le dal dans notre premier tutoriel, Visual Studio a automatiquement ajouté des méthodes pour l’insertion, la mise à jour et la suppression de données de la table de base de données sous-jacente. De plus, dans La création d’une couche logique métier, nous avons conçu des méthodes dans la BLL qui a appelé dans ces méthodes DAL de modification de données.

En plus de sa Select() méthode, ObjectDataSource possède Insert()également , Update()et Delete() des méthodes. Comme la Select() méthode, ces trois méthodes peuvent être mappées à des méthodes dans un objet sous-jacent. Lorsqu’ils sont configurés pour insérer, mettre à jour ou supprimer des données, les contrôles GridView, DetailsView et FormView fournissent une interface utilisateur pour modifier les données sous-jacentes. Cette interface utilisateur appelle les Insert()méthodes , Update()et Delete() les méthodes de ObjectDataSource, qui appellent ensuite les méthodes associées de l’objet sous-jacent (voir la figure 1).

Les méthodes Insert(), Update() et Delete() de ObjectDataSource servent de proxy dans la BLL

Figure 1 : Les méthodes et Delete() les Update()méthodes objectDataSource servent de proxy dans la BLL (Cliquez pour afficher l’image Insert()de taille complète)

Dans ce tutoriel, nous allons voir comment mapper les contrôles ObjectDataSource Insert(), Update()ainsi Delete() que les méthodes des classes dans la BLL, ainsi que comment configurer les contrôles GridView, DetailsView et FormView pour fournir des fonctionnalités de modification des données.

Étape 1 : Création des pages web d’insertion, de mise à jour et de suppression

Avant de commencer à explorer comment insérer, mettre à jour et supprimer des données, commençons par prendre un moment pour créer les pages ASP.NET dans notre projet de site web dont nous aurons besoin pour ce didacticiel et les plusieurs suivantes. Commencez par ajouter un nouveau dossier nommé EditInsertDelete. Ensuite, ajoutez les ASP.NET pages suivantes à ce dossier, en veillant à associer chaque page à la Site.master page maître :

  • Default.aspx
  • Basics.aspx
  • DataModificationEvents.aspx
  • ErrorHandling.aspx
  • UIValidation.aspx
  • CustomizedUI.aspx
  • OptimisticConcurrency.aspx
  • ConfirmationOnDelete.aspx
  • UserLevelAccess.aspx

Ajouter les pages ASP.NET pour les didacticiels relatifs aux modifications de données

Figure 2 : Ajouter les pages ASP.NET pour les didacticiels liés à la modification des données

Comme dans les autres dossiers, Default.aspx dans le EditInsertDelete dossier répertorie les didacticiels de sa section. Rappelez-vous que le SectionLevelTutorialListing.ascx contrôle utilisateur fournit cette fonctionnalité. Par conséquent, ajoutez ce contrôle utilisateur en Default.aspx le faisant glisser de l’Explorateur de solutions dans l’affichage Création de la page.

Ajoutez le contrôle utilisateur SectionLevelTutorialListing.ascx à Default.aspx

Figure 3 : Ajouter le contrôle utilisateur à Default.aspx (Cliquez pour afficher l’image SectionLevelTutorialListing.ascxde taille complète)

Enfin, ajoutez les pages en tant qu’entrées au Web.sitemap fichier. Plus précisément, ajoutez le balisage suivant après la mise en forme <siteMapNode>personnalisée :

<siteMapNode title="Editing, Inserting, and Deleting" url="~/EditInsertDelete/Default.aspx" description="Samples of Reports that Provide Editing, Inserting, and Deleting Capabilities"> <siteMapNode url="~/EditInsertDelete/Basics.aspx" title="Basics" description="Examines the basics of data modification with the GridView, DetailsView, and FormView controls." /> <siteMapNode url="~/EditInsertDelete/DataModificationEvents.aspx" title="Data Modification Events" description="Explores the events raised by the ObjectDataSource pertinent to data modification." /> <siteMapNode url="~/EditInsertDelete/ErrorHandling.aspx" title="Error Handling" description="Learn how to gracefully handle exceptions raised during the data modification workflow." /> <siteMapNode url="~/EditInsertDelete/UIValidation.aspx" title="Adding Data Entry Validation" description="Help prevent data entry errors by providing validation." /> <siteMapNode url="~/EditInsertDelete/CustomizedUI.aspx" title="Customize the User Interface" description="Customize the editing and inserting user interfaces." /> <siteMapNode url="~/EditInsertDelete/OptimisticConcurrency.aspx" title="Optimistic Concurrency" description="Learn how to help prevent simultaneous users from overwritting one another s changes." /> <siteMapNode url="~/EditInsertDelete/ConfirmationOnDelete.aspx" title="Confirm On Delete" description="Prompt a user for confirmation when deleting a record." /> <siteMapNode url="~/EditInsertDelete/UserLevelAccess.aspx" title="Limit Capabilities Based on User" description="Learn how to limit the data modification functionality based on the user role or permissions." /> </siteMapNode>

Après la mise à jour Web.sitemap, prenez un moment pour afficher le site web des didacticiels via un navigateur. Le menu de gauche inclut désormais des éléments pour les didacticiels d’édition, d’insertion et de suppression.

La carte de site inclut désormais des entrées pour les didacticiels d’édition, d’insertion et de suppression

Figure 4 : La carte de site inclut désormais des entrées pour les didacticiels d’édition, d’insertion et de suppression

Étape 2 : Ajout et configuration du contrôle ObjectDataSource

Étant donné que GridView, DetailsView et FormView diffèrent chacun dans leurs fonctionnalités de modification et disposition des données, examinons chacun d’eux individuellement. Au lieu d’avoir chaque contrôle à l’aide de son propre ObjectDataSource, nous allons simplement créer un seul ObjectDataSource que les trois exemples de contrôle peuvent partager.

Ouvrez la Basics.aspx page, faites glisser un ObjectDataSource à partir de la boîte à outils sur le Concepteur, puis cliquez sur le lien Configurer la source de données à partir de sa balise active. Étant donné que la ProductsBLL seule classe BLL qui fournit des méthodes d’édition, d’insertion et de suppression, configurez ObjectDataSource pour utiliser cette classe.

Configurer ObjectDataSource pour utiliser la classe ProductsBLL

Figure 5 : Configurer ObjectDataSource pour utiliser la classe (Cliquez pour afficher l’image ProductsBLLde taille complète)

Dans l’écran suivant, nous pouvons spécifier quelles méthodes de la ProductsBLL classe sont mappées à l’objetDataSource, Insert()Update()et Delete() en sélectionnant l’onglet Select()approprié et en choisissant la méthode dans la liste déroulante. La figure 6, qui doit maintenant être familière, mappe la méthode ObjectDataSource Select() à la méthode de GetProducts() la ProductsBLL classe. Les Insert()méthodes et Delete() les méthodes Update()peuvent être configurées en sélectionnant l’onglet approprié dans la liste en haut.

Avoir l’objet ObjectDataSource Return All of the Products

Figure 6 : Obtenir le retour ObjectDataSource de tous les produits (cliquez pour afficher l’image de taille complète)

Les figures 7, 8 et 9 affichent les onglets UPDATE, INSERT et DELETE de ObjectDataSource. Configurez ces onglets pour que les Insert()méthodes , Update()et Delete() les méthodes appellent respectivement les méthodes et DeleteProduct les méthodes AddProductde UpdateProductla ProductsBLL classe.

Mapper la méthode Update() de ObjectDataSource à la méthode UpdateProduct de la classe ProductBLL

Figure 7 : Mapper la méthode ObjectDataSource à la méthode de Update() UpdateProduct la ProductBLL classe (Click pour afficher l’image de taille complète)

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

Figure 8 : Mapper la méthode ObjectDataSource Insert() à la méthode Add Product de la ProductBLL classe (Cliquez pour afficher l’image de taille complète)

Mapper la méthode Delete() d’ObjectDataSource à la méthode DeleteProduct de la classe ProductBLL

Figure 9 : Mapper la méthode ObjectDataSource à la méthode de Delete() DeleteProduct la ProductBLL classe (Click pour afficher l’image de taille complète)

Vous avez peut-être remarqué que les listes déroulantes dans les onglets UPDATE, INSERT et DELETE avaient déjà sélectionné ces méthodes. C’est grâce à notre utilisation du DataObjectMethodAttribute qui décore les méthodes de ProductsBLL. Par exemple, la méthode DeleteProduct a la signature suivante :

<System.ComponentModel.DataObjectMethodAttribute _ (System.ComponentModel.DataObjectMethodType.Delete, True)> _ Public Function DeleteProduct(ByVal productID As Integer) As Boolean End Function

L’attribut DataObjectMethodAttribute indique l’objectif de chaque méthode s’il s’agit de sélectionner, d’insérer, de mettre à jour ou de supprimer et s’il s’agit ou non de la valeur par défaut. Si vous avez omis ces attributs lors de la création de vos classes BLL, vous devez sélectionner manuellement les méthodes sous les onglets UPDATE, INSERT et DELETE.

Après avoir vérifié que les méthodes appropriées ProductsBLL sont mappées aux méthodes , Update()et Delete() aux méthodes de ObjectDataSource, cliquez sur Terminer pour terminer l’AssistantInsert().

Examen du balisage d’ObjectDataSource

Après avoir configuré ObjectDataSource via son Assistant, accédez à la vue Source pour examiner le balisage déclaratif généré. La <asp:ObjectDataSource> balise spécifie l’objet sous-jacent et les méthodes à appeler. En outre, il existe DeleteParameters, UpdateParameterset InsertParameters qui mappent aux paramètres d’entrée pour les méthodes et DeleteProduct les méthodes de AddProductUpdateProductla ProductsBLL classe :

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DeleteMethod="DeleteProduct" InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts" TypeName="ProductsBLL" UpdateMethod="UpdateProduct"> <DeleteParameters> <asp:Parameter Name="productID" Type="Int32" /> </DeleteParameters> <UpdateParameters> <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" /> <asp:Parameter Name="productID" Type="Int32" /> </UpdateParameters> <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>

ObjectDataSource inclut un paramètre pour chacun des paramètres d’entrée de ses méthodes associées, tout comme une liste de SelectParameter s est présente lorsque ObjectDataSource est configuré pour appeler une méthode select qui attend un paramètre d’entrée (par exemple GetProductsByCategoryID(categoryID)). Comme nous le verrons sous peu, les valeurs de ces DeleteParametersvaleurs UpdateParameterssont InsertParameters définies automatiquement par GridView, DetailsView et FormView avant d’appeler Insert()la méthode , Update()ou Delete() objectDataSource. Ces valeurs peuvent également être définies par programmation en fonction des besoins, car nous allons discuter dans un prochain tutoriel.

L’un des effets secondaires de l’utilisation de l’Assistant pour configurer objectDataSource est que Visual Studio définit la propriété original_{0}OldValuesParameterFormatString sur . Cette valeur de propriété est utilisée pour inclure les valeurs d’origine des données en cours de modification et est utile dans deux scénarios :

  • Si, lors de la modification d’un enregistrement, les utilisateurs peuvent modifier la valeur de clé primaire. Dans ce cas, la nouvelle valeur de clé primaire et la valeur de clé primaire d’origine doivent être fournies afin que l’enregistrement avec la valeur de clé primaire d’origine soit trouvé et que sa valeur soit mise à jour en conséquence.
  • Lors de l’utilisation d’une concurrence optimiste. L’accès concurrentiel optimiste est une technique permettant de s’assurer que deux utilisateurs simultanés ne remplacent pas les modifications des uns des autres et sont la rubrique d’un didacticiel futur.

La OldValuesParameterFormatString propriété indique le nom des paramètres d’entrée dans les méthodes de mise à jour et de suppression de l’objet sous-jacent pour les valeurs d’origine. Nous aborderons cette propriété et son objectif plus en détail lorsque nous explorerons l’accès concurrentiel optimiste. Je l’apporte maintenant, cependant, parce que les méthodes de notre BLL ne s’attendent pas aux valeurs d’origine et, par conséquent, il est important que nous supprimions cette propriété. Le fait de laisser la OldValuesParameterFormatString propriété définie sur quelque chose d’autre que la valeur par défaut ({0}) entraîne une erreur lorsqu’un contrôle Web de données tente d’appeler les méthodes ou Delete() les Update() méthodes de ObjectDataSource, car ObjectDataSource tente de passer à la fois les UpdateParameters paramètres de valeur ou DeleteParameters spécifiés ainsi que les paramètres de valeur d’origine.

Si ce n’est pas terriblement clair à ce stade, ne vous inquiétez pas, nous examinerons cette propriété et son utilitaire dans un prochain tutoriel. Pour l’instant, veillez simplement à supprimer entièrement cette déclaration de propriété de la syntaxe déclarative ou définissez la valeur sur la valeur par défaut ({0}).

Remarque

Si vous effacez simplement la valeur de la OldValuesParameterFormatString propriété de l’Fenêtre Propriétés dans la vue Création, la propriété existe toujours dans la syntaxe déclarative, mais elle est définie sur une chaîne vide. Cela, malheureusement, entraînera toujours le même problème abordé ci-dessus. Par conséquent, supprimez complètement la propriété de la syntaxe déclarative ou, du Fenêtre Propriétés, définissez la valeur sur la valeur par défaut. {0}

Étape 3 : Ajout d’un contrôle web de données et configuration de celui-ci pour la modification des données

Une fois que ObjectDataSource a été ajouté à la page et configuré, nous sommes prêts à ajouter des contrôles Web de données à la page pour afficher les données et fournir un moyen pour l’utilisateur final de le modifier. Nous allons examiner les contrôles GridView, DetailsView et FormView séparément, car ces contrôles Web de données diffèrent dans leurs fonctionnalités et configuration de modification des données.

Comme nous le verrons dans le reste de cet article, l’ajout de la modification, de l’insertion et de la suppression de la prise en charge par le biais des contrôles GridView, DetailsView et FormView est vraiment aussi simple que de vérifier quelques cases à cocher. Il existe de nombreuses subtilités et cas d’arête dans le monde réel qui rendent ces fonctionnalités plus impliquées que simplement pointer et cliquer. Toutefois, ce tutoriel se concentre uniquement sur la preuve des fonctionnalités de modification des données simplistes. Les didacticiels futurs examineront les préoccupations qui se poseront sans aucun doute dans un cadre réel.

Suppression de données à partir de GridView

Commencez par faire glisser un GridView à partir de la boîte à outils vers le Concepteur. Ensuite, liez ObjectDataSource à GridView en le sélectionnant dans la liste déroulante dans la balise active de GridView. À ce stade, le balisage déclaratif de GridView sera :

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"> <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>

La liaison de GridView à ObjectDataSource via sa balise active présente deux avantages :

  • BoundFields et CheckBoxFields sont créés automatiquement pour chacun des champs retournés par ObjectDataSource. De plus, les propriétés boundField et CheckBoxField sont définies en fonction des métadonnées du champ sous-jacent. Par exemple, les ProductIDchamps et SupplierName les CategoryNamechamps sont marqués comme étant en lecture seule et ne doivent donc pas être mis à jour lors de la ProductsDataTable modification. Pour ce faire, ces propriétés ReadOnly de BoundFields sont définies Truesur .
  • La propriété DataKeyNames est affectée aux champs de clé primaire de l’objet sous-jacent. Cela est essentiel lors de l’utilisation de GridView pour modifier ou supprimer des données, car cette propriété indique le champ (ou l’ensemble de champs) qui identifie chaque enregistrement. Pour plus d’informations sur la DataKeyNames propriété, reportez-vous à la section Master/Detail Using a Selectable Master GridView with a Details DetailView tutorial.

Bien que GridView puisse être lié à ObjectDataSource par le biais de la syntaxe Fenêtre Propriétés ou déclarative, cela vous oblige à ajouter manuellement l’objet BoundField et DataKeyNames le balisage appropriés.

Le contrôle GridView prend en charge la prise en charge intégrée de la modification et de la suppression au niveau des lignes. La configuration d’un GridView pour prendre en charge la suppression ajoute une colonne de boutons Supprimer. Lorsque l’utilisateur final clique sur le bouton Supprimer pour une ligne particulière, un postback se produit et GridView effectue les étapes suivantes :

  1. La ou les valeurs de ObjectDataSource DeleteParameters sont affectées
  2. La méthode ObjectDataSource est appelée, en supprimant l’enregistrement Delete() spécifié
  3. GridView se connecte à ObjectDataSource en appelant sa Select() méthode

Les valeurs attribuées sont DeleteParameters les valeurs des champs de la DataKeyNames ligne sur laquelle le bouton Supprimer a été cliqué. Par conséquent, il est essentiel qu’une DataKeyNames propriété gridView soit correctement définie. S’il est manquant, la DeleteParameters valeur Nothing est affectée à l’étape 1, ce qui, à son tour, n’entraîne pas de suppression d’enregistrements à l’étape 2.

Remarque

La DataKeys collection est stockée dans l’état de contrôle de GridView, ce qui signifie que les DataKeys valeurs seront mémorisées dans une publication différée même si l’état d’affichage de GridView a été désactivé. Toutefois, il est très important que l’état d’affichage reste activé pour les GridViews qui prennent en charge la modification ou la suppression (comportement par défaut). Si vous définissez la propriété falseGridView EnableViewState sur , le comportement de modification et de suppression fonctionne correctement pour un seul utilisateur, mais s’il existe des utilisateurs simultanés qui suppriment des données, il existe la possibilité que ces utilisateurs simultanés puissent supprimer ou modifier accidentellement des enregistrements qu’ils n’ont pas l’intention.

Ce même avertissement s’applique également aux DetailsViews et Aux FormViews.

Pour ajouter des fonctionnalités de suppression à un GridView, il vous suffit d’accéder à sa balise active et de cocher la case Activer la suppression.

Cochez la case Activer la suppression

Figure 10 : Cochez la case Activer la suppression

La case Activer la suppression à partir de la balise active ajoute un Champ de commande à GridView. CommandField affiche une colonne dans GridView avec des boutons pour effectuer une ou plusieurs des tâches suivantes : sélection d’un enregistrement, modification d’un enregistrement et suppression d’un enregistrement. Nous avons vu précédemment CommandField en action avec la sélection d’enregistrements dans master/detail à l’aide d’un contrôle Master GridView sélectionnable avec un didacticiel DetailsView .

CommandField contient un certain nombre de ShowXButton propriétés qui indiquent quelle série de boutons sont affichées dans CommandField. En cochant la case Activer la suppression d’un Champ de commande dont ShowDeleteButton la propriété True a été ajoutée à la collection Columns de GridView.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"> <Columns> <asp:CommandField ShowDeleteButton="True" /> ... BoundFields removed for brevity ... </Columns> </asp:GridView>

À ce stade, croyez-le ou non, nous avons terminé d’ajouter la prise en charge de suppression à GridView ! Comme le montre la figure 11, lors de la visite de cette page via un navigateur, une colonne de boutons Supprimer est présente.

CommandField ajoute une colonne de boutons Supprimer

Figure 11 : Le Champ de commande ajoute une colonne de boutons Supprimer (cliquez pour afficher l’image de taille complète)

Si vous avez créé ce didacticiel à partir de la base sur vous-même, lorsque vous testez cette page en cliquant sur le bouton Supprimer, une exception s’affiche. Poursuivez la lecture pour savoir pourquoi ces exceptions ont été soulevées et comment les corriger.

Remarque

Si vous suivez le téléchargement qui accompagne ce didacticiel, ces problèmes ont déjà été pris en compte. Toutefois, je vous encourage à lire les détails répertoriés ci-dessous pour vous aider à identifier les problèmes qui peuvent survenir et les solutions de contournement appropriées.

Si, lorsque vous tentez de supprimer un produit, vous obtenez une exception dont le message est similaire à « ObjectDataSource « ObjectDataSource1 » n’a pas pu trouver une méthode non générique « DeleteProduct » qui a des paramètres : productID, original_ProductID », vous avez probablement oublié de supprimer la OldValuesParameterFormatString propriété de ObjectDataSource. Avec la OldValuesParameterFormatString propriété spécifiée, ObjectDataSource tente de transmettre les paramètres d’entrée et original_ProductID de saisie productID à la DeleteProduct méthode. DeleteProduct, toutefois, accepte uniquement un paramètre d’entrée unique, d’où l’exception. La suppression de la OldValuesParameterFormatString propriété (ou sa définition {0}) indique à ObjectDataSource de ne pas tenter de transmettre le paramètre d’entrée d’origine.

Vérifiez que la propriété OldValuesParameterFormatString a été effacée

Figure 12 : Vérifier que la OldValuesParameterFormatString propriété a été effacée (cliquez pour afficher l’image de taille complète)

Même si vous avez supprimé la OldValuesParameterFormatString propriété, vous obtiendrez toujours une exception lors de la tentative de suppression d’un produit avec le message : « L’instruction DELETE est en conflit avec la contrainte REFERENCE « FK_Order_Details_Products ». La base de données Northwind contient une contrainte de clé étrangère entre la Order Details Products table, ce qui signifie qu’un produit ne peut pas être supprimé du système s’il existe un ou plusieurs enregistrements pour celui-ci dans la Order Details table. Étant donné que chaque produit de la base de données Northwind contient au moins un enregistrement Order Details, nous ne pouvons pas supprimer de produits tant que nous n’avons pas supprimé les enregistrements de détails de commande associés du produit.

Une contrainte de clé étrangère interdit la suppression de produits

Figure 13 : Une contrainte de clé étrangère interdit la suppression de produits (cliquez pour afficher l’image de taille complète)

Pour notre tutoriel, nous allons simplement supprimer tous les enregistrements de la Order Details table. Dans une application réelle, nous devons effectuer les opérations suivantes :

  • Avoir un autre écran pour gérer les informations sur les détails de commande
  • Augmenter la méthode pour inclure la DeleteProduct logique pour supprimer les détails de commande du produit spécifié
  • Modifiez la requête SQL utilisée par TableAdapter pour inclure la suppression des détails de commande du produit spécifié

Nous allons simplement supprimer tous les enregistrements de la Order Details table pour contourner la contrainte de clé étrangère. Accédez à l’Explorateur de serveurs dans Visual Studio, cliquez avec le bouton droit sur le NORTHWND.MDF nœud, puis choisissez Nouvelle requête. Ensuite, dans la fenêtre de requête, exécutez l’instruction SQL suivante : DELETE FROM [Order Details]

Supprimer tous les enregistrements de la table Détails de la commande

Figure 14 : Supprimer tous les enregistrements du Order Details tableau (cliquez pour afficher l’image de taille complète)

Après avoir supprimé la Order Details table en cliquant sur le bouton Supprimer, le produit sera supprimé sans erreur. Si vous cliquez sur le bouton Supprimer ne supprime pas le produit, vérifiez que la propriété de GridView DataKeyNames est définie sur le champ de clé primaire (ProductID).

Remarque

Lorsque vous cliquez sur le bouton Supprimer, une publication se produit et l’enregistrement est supprimé. Cela peut être dangereux, car il est facile de cliquer accidentellement sur le bouton Supprimer de la ligne incorrecte. Dans un prochain tutoriel, nous allons voir comment ajouter une confirmation côté client lors de la suppression d’un enregistrement.

Modification de données avec GridView

Outre la suppression, le contrôle GridView fournit également une prise en charge intégrée de l’édition au niveau des lignes. La configuration d’un GridView pour prendre en charge la modification ajoute une colonne de boutons Modifier. Du point de vue de l’utilisateur final, le fait de cliquer sur le bouton Modifier d’une ligne entraîne la modification de cette ligne, en transformant les cellules en zones de texte contenant les valeurs existantes et en remplaçant le bouton Modifier par des boutons Mettre à jour et Annuler. Après avoir apporté leurs modifications souhaitées, l’utilisateur final peut cliquer sur le bouton Mettre à jour pour valider les modifications ou le bouton Annuler pour les ignorer. Dans les deux cas, après avoir cliqué sur Update ou Cancel the GridView retourne à son état de préversion.

Du point de vue du développeur de pages, lorsque l’utilisateur final clique sur le bouton Modifier pour une ligne particulière, un postback se produit et gridView effectue les étapes suivantes :

  1. La propriété gridView est affectée à l’index EditItemIndex de la ligne dont le bouton Modifier a été cliqué
  2. GridView se connecte à ObjectDataSource en appelant sa Select() méthode
  3. Index de ligne qui correspond au EditItemIndex rendu en « mode d’édition ». Dans ce mode, le bouton Modifier est remplacé par les boutons Update et Cancel et BoundFields dont ReadOnly les propriétés sont False (valeur par défaut) sont affichées en tant que contrôles Web TextBox dont Text les propriétés sont affectées aux valeurs des champs de données.

À ce stade, le balisage est retourné au navigateur, ce qui permet à l’utilisateur final d’apporter des modifications aux données de la ligne. Lorsque l’utilisateur clique sur le bouton Mettre à jour, une publication se produit et GridView effectue les étapes suivantes :

  1. La ou les valeurs de ObjectDataSource UpdateParameters sont affectées aux valeurs entrées par l’utilisateur final dans l’interface d’édition de GridView.
  2. La méthode ObjectDataSource est appelée, mettant à jour l’enregistrement Update() spécifié
  3. GridView se connecte à ObjectDataSource en appelant sa Select() méthode

Les valeurs de clé primaire attribuées à l’étape UpdateParameters 1 proviennent des valeurs spécifiées dans la DataKeyNames propriété, tandis que les valeurs de clé non primaire proviennent du texte des contrôles Web TextBox pour la ligne modifiée. Comme pour la suppression, il est essentiel qu’une DataKeyNames propriété gridView soit correctement définie. S’il est manquant, la UpdateParameters valeur de la clé primaire est affectée à une valeur de Nothing l’étape 1, ce qui n’entraîne pas à son tour les enregistrements mis à jour à l’étape 2.

Vous pouvez activer la fonctionnalité d’édition en cochant simplement la case Activer la modification dans la balise active de GridView.

Cochez la case Activer la modification

Figure 15 : Cochez la case Activer la modification

La case Activer la modification ajoute un Champ de commande (si nécessaire) et définit sa ShowEditButton propriété Truesur . Comme nous l’avons vu précédemment, CommandField contient un certain nombre de ShowXButton propriétés qui indiquent quelle série de boutons sont affichées dans CommandField. La case Activer la modification ajoute la ShowEditButton propriété à l’objet CommandField existant :

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"> <Columns> <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" /> ... BoundFields removed for brevity ... </Columns> </asp:GridView>

C’est tout ce qu’il y a à ajouter la prise en charge des éditions rudimentaires. Comme le montre la figure 16, l’interface d’édition est plutôt brute chaque BoundField dont ReadOnly la propriété est définie False sur (la valeur par défaut) est affichée sous la forme d’une zone de texte. Cela inclut des champs tels CategoryID que et SupplierID, qui sont des clés pour d’autres tables.

Cliquer sur le bouton Modifier du Chai affiche la ligne en mode Édition

Figure 16 : Cliquer sur le bouton Modifier du Chai affiche la ligne en mode Édition (cliquez pour afficher l’image de taille complète)

En plus de demander aux utilisateurs de modifier directement les valeurs de clé étrangère, l’interface de l’interface d’édition ne dispose pas des méthodes suivantes :

  • Si l’utilisateur entre un CategoryID ou SupplierID qui n’existe pas dans la base de données, il UPDATE enfreint une contrainte de clé étrangère, ce qui entraîne le levée d’une exception.
  • L’interface d’édition n’inclut aucune validation. Si vous ne fournissez pas de valeur requise (par exemple ProductName), ou entrez une valeur de chaîne où une valeur numérique est attendue (par exemple, en entrant « Trop ! » dans la UnitPrice zone de texte), une exception est levée. Un prochain tutoriel explique comment ajouter des contrôles de validation à l’interface utilisateur d’édition.
  • Actuellement, tous les champs de produit qui ne sont pas en lecture seule doivent être inclus dans GridView. Si nous étions à supprimer un champ de GridView, par exemple UnitPrice, lors de la mise à jour des données, GridView ne définirait pas la UnitPrice UpdateParameters valeur, ce qui modifierait l’enregistrement de base de UnitPrice données en valeur NULL . De même, si un champ obligatoire, tel que ProductName, est supprimé de GridView, la mise à jour échoue avec la même exception « Column 'ProductName' ne permet pas les valeurs Null » mentionnées ci-dessus.
  • La mise en forme de l’interface d’édition laisse beaucoup à désirer. La valeur UnitPrice est affichée avec quatre décimales. Dans l’idéal, les CategoryID valeurs contiennent SupplierID des Listes déroulantes qui répertorient les catégories et fournisseurs dans le système.

Il s’agit de toutes les lacunes avec lesquelles nous devrons vivre pour l’instant, mais seront traitées dans les prochains didacticiels.

Insertion, modification et suppression de données avec DetailsView

Comme nous l’avons vu dans les didacticiels précédents, le contrôle DetailsView affiche un enregistrement à la fois et, comme GridView, permet de modifier et de supprimer l’enregistrement actuellement affiché. L’expérience de l’utilisateur final avec la modification et la suppression d’éléments à partir d’un DetailsView et du flux de travail du côté ASP.NET est identique à celle de GridView. Lorsque DetailsView diffère de GridView, il fournit également une prise en charge intégrée de l’insertion.

Pour illustrer les fonctionnalités de modification de données de GridView, commencez par ajouter un DetailsView à la Basics.aspx page au-dessus de gridView existant et liez-le à l’objet ObjectDataSource existant via la balise active DetailsView. Ensuite, désactivez les propriétés et Width les propriétés de Height DetailsView, puis cochez l’option Activer la pagination à partir de la balise active. Pour activer la modification, l’insertion et la suppression de la prise en charge, cochez simplement les cases Activer l’édition, Activer l’insertion et Activer la suppression dans la balise active.

Capture d’écran montrant la fenêtre Tâches DetailsView avec les cases Activer l’insertion, Activer l’édition et Activer la suppression activées.

Figure 17 : Configurer DetailsView pour prendre en charge la modification, l’insertion et la suppression

Comme avec GridView, l’ajout de la modification, de l’insertion ou de la suppression de la prise en charge ajoute un Champ de commande à DetailsView, comme le montre la syntaxe déclarative suivante :

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"> <Fields> <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" /> <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" ShowInsertButton="True" /> </Fields> </asp:DetailsView>

Notez que pour DetailsView, le Champ de commande s’affiche à la fin de la collection Columns par défaut. Étant donné que les champs de DetailsView sont affichés sous forme de lignes, le Champ de commande s’affiche sous forme de ligne avec des boutons Insérer, Modifier et Supprimer en bas de DetailsView.

Capture d’écran de DetailsView avec le Champ de commande qui s’affiche sous la forme d’une ligne inférieure avec des boutons Insérer, Modifier et Supprimer.

Figure 18 : Configurer DetailsView pour prendre en charge la modification, l’insertion et la suppression (cliquez pour afficher l’image de taille complète)

Cliquer sur le bouton Supprimer démarre la même séquence d’événements qu’avec GridView : publication différée ; suivi de DetailsView remplit ses ObjectDataSource en fonction DataKeyNames des DeleteParameters valeurs ; et terminé avec un appel de Delete() la méthode ObjectDataSource, qui supprime réellement le produit de la base de données. La modification dans DetailsView fonctionne également de manière identique à celle de GridView.

Pour l’insertion, l’utilisateur final reçoit un bouton Nouveau qui, lorsqu’il clique, affiche le DetailsView en « mode Insertion ». Avec le « mode d’insertion », le bouton Nouveau est remplacé par les boutons Insérer et Annuler, et seuls ceux BoundFields dont InsertVisible la propriété est définie True sur (valeur par défaut) s’affichent. Ces champs de données identifiés comme des champs d’incrément automatique, tels que ProductID, ont leur propriété InsertVisible définie False lors de la liaison de DetailsView à la source de données via la balise active.

Lors de la liaison d’une source de données à un DetailsView via la balise active, Visual Studio définit la InsertVisible propriété sur False uniquement pour les champs d’incrément automatique. Les champs en lecture seule, tels CategoryName que et SupplierName, sont affichés dans l’interface utilisateur « mode d’insertion », sauf si leur InsertVisible propriété est explicitement définie Falsesur . Prenez un moment pour définir les propriétés Falsede InsertVisible ces deux champs , soit via la syntaxe déclarative de DetailsView, soit via le lien Modifier les champs dans la balise active. La figure 19 montre la définition des InsertVisible propriétés False en cliquant sur le lien Modifier les champs.

Capture d’écran montrant la fenêtre Champs avec la propriété InsertVisible définie sur False.

Figure 19 : Northwind Traders Propose désormais le thé Acme (cliquez pour afficher l’image de taille complète)

Après avoir défini les propriétés, affichez la InsertVisible Basics.aspx page dans un navigateur et cliquez sur le bouton Nouveau. La figure 20 montre le DetailsView lors de l’ajout d’une nouvelle boisson, Acme Tea, à notre gamme de produits.

Capture d’écran montrant DetailsView de la page Basics.aspx dans un navigateur web.

Figure 20 : Northwind Traders Propose désormais le thé Acme (cliquez pour afficher l’image de taille complète)

Après avoir entré les détails d’Acme Tea et en cliquant sur le bouton Insérer, un postback s’affiche et le nouvel enregistrement est ajouté à la Products table de base de données. Étant donné que ce DetailsView répertorie les produits dans l’ordre avec lequel ils existent dans la table de base de données, nous devons mettre en page le dernier produit pour voir le nouveau produit.

Détails du thé Acme

Figure 21 : Détails du thé Acme (cliquez pour afficher l’image de taille complète)

Remarque

La propriété CurrentMode de DetailsView indique l’interface affichée et peut être l’une des valeurs suivantes : Edit, Insertou ReadOnly. La propriété DefaultMode indique le mode auquel DetailsView revient une fois qu’une modification ou une insertion a été terminée et est utile pour afficher un DetailsView qui est définitivement en mode Édition ou Insertion.

Le point et cliquez sur les fonctionnalités d’insertion et de modification du DetailsView souffrent des mêmes limitations que GridView : l’utilisateur doit entrer des valeurs existantes CategoryID et SupplierID des valeurs via une zone de texte ; l’interface ne dispose pas d’une logique de validation ; tous les champs de produit qui n’autorisent NULL pas les valeurs ou qui n’ont pas de valeur par défaut spécifiée au niveau de la base de données doivent être inclus dans l’interface d’insertion, et ainsi de suite.

Les techniques que nous examinerons pour étendre et améliorer l’interface d’édition de GridView dans les articles futurs peuvent également être appliquées aux interfaces d’édition et d’insertion du contrôle DetailsView.

Utilisation de FormView pour une interface utilisateur de modification de données plus flexible

FormView offre une prise en charge intégrée de l’insertion, de la modification et de la suppression de données, mais, étant donné qu’il utilise des modèles au lieu de champs, il n’y a pas d’emplacement pour ajouter boundFields ou CommandField utilisé par les contrôles GridView et DetailsView pour fournir l’interface de modification des données. Au lieu de cela, cette interface permet aux contrôles Web de collecter les entrées utilisateur lors de l’ajout d’un nouvel élément ou de la modification d’un élément existant avec les boutons Nouveau, Modifier, Supprimer, Insérer, Mettre à jour et Annuler doivent être ajoutés manuellement aux modèles appropriés. Heureusement, Visual Studio crée automatiquement l’interface nécessaire lors de la liaison de FormView à une source de données via la liste déroulante dans sa balise active.

Pour illustrer ces techniques, commencez par ajouter un FormView à la Basics.aspx page et, à partir de la balise active de FormView, liez-la à l’ObjetDataSource déjà créée. Cela génère un EditItemTemplate, InsertItemTemplateet ItemTemplate pour formView avec des contrôles Web TextBox pour collecter les contrôles Web d’entrée et de bouton de l’utilisateur pour les boutons Nouveau, Modifier, Supprimer, Insérer, Mettre à jour et Annuler. En outre, la propriété de DataKeyNames FormView est définie sur le champ de clé primaire (ProductID) de l’objet retourné par ObjectDataSource. Enfin, cochez l’option Activer la pagination dans la balise active de FormView.

L’exemple suivant montre le balisage déclaratif des éléments FormView une fois que FormView ItemTemplate a été lié à ObjectDataSource. Par défaut, chaque champ de produit de valeur non booléenne est lié à la Text propriété d’un contrôle Label Web, tandis que chaque champ de valeur booléen (Discontinued) est lié à la Checked propriété d’un contrôle Web CheckBox désactivé. Pour que les boutons Nouveau, Modifier et Supprimer déclenchent un certain comportement FormView lorsqu’ils cliquent, il est impératif que leurs CommandName valeurs soient définies Newsur , Editet Delete, respectivement.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"> <EditItemTemplate> ... </EditItemTemplate> <InsertItemTemplate> ... </InsertItemTemplate> <ItemTemplate> ProductID: <asp:Label ID="ProductIDLabel" runat="server" Text='<%# Eval("ProductID") %>'></asp:Label><br /> ProductName: <asp:Label ID="ProductNameLabel" runat="server" Text='<%# Bind("ProductName") %>'> </asp:Label><br /> SupplierID: <asp:Label ID="SupplierIDLabel" runat="server" Text='<%# Bind("SupplierID") %>'> </asp:Label><br /> CategoryID: <asp:Label ID="CategoryIDLabel" runat="server" Text='<%# Bind("CategoryID") %>'> </asp:Label><br /> QuantityPerUnit: <asp:Label ID="QuantityPerUnitLabel" runat="server" Text='<%# Bind("QuantityPerUnit") %>'> </asp:Label><br /> UnitPrice: <asp:Label ID="UnitPriceLabel" runat="server" Text='<%# Bind("UnitPrice") %>'></asp:Label><br /> UnitsInStock: <asp:Label ID="UnitsInStockLabel" runat="server" Text='<%# Bind("UnitsInStock") %>'> </asp:Label><br /> UnitsOnOrder: <asp:Label ID="UnitsOnOrderLabel" runat="server" Text='<%# Bind("UnitsOnOrder") %>'> </asp:Label><br /> ReorderLevel: <asp:Label ID="ReorderLevelLabel" runat="server" Text='<%# Bind("ReorderLevel") %>'> </asp:Label><br /> Discontinued: <asp:CheckBox ID="DiscontinuedCheckBox" runat="server" Checked='<%# Bind("Discontinued") %>' Enabled="false" /><br /> CategoryName: <asp:Label ID="CategoryNameLabel" runat="server" Text='<%# Bind("CategoryName") %>'> </asp:Label><br /> SupplierName: <asp:Label ID="SupplierNameLabel" runat="server" Text='<%# Bind("SupplierName") %>'> </asp:Label><br /> <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"> </asp:LinkButton> <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete"> </asp:LinkButton> <asp:LinkButton ID="NewButton" runat="server" CausesValidation="False" CommandName="New" Text="New"> </asp:LinkButton> </ItemTemplate> </asp:FormView>

La figure 22 montre les vues de FormView lorsqu’elles ItemTemplate sont consultées via un navigateur. Chaque champ de produit est répertorié avec les boutons Nouveau, Modifier et Supprimer en bas.

Le composant FormView ItemTemplate de defaut répertorie chaque champ de produit avec les boutons Nouveaux, Modifier et Supprimer

Figure 22 : Le formulaire Defaut ItemTemplate répertorie chaque champ de produit, ainsi que les boutons Nouveau, Modifier et Supprimer (cliquez pour afficher l’image de taille complète)

Comme avec GridView et DetailsView, le fait de cliquer sur le bouton Supprimer ou n’importe quel bouton, LinkButton ou ImageButton dont CommandName la propriété est définie sur Delete provoque une publication, remplit les données ObjectDataSource en fonction de DeleteParameters la valeur de DataKeyNames FormView et appelle la méthode ObjectDataSource Delete() .

Lorsque le bouton Modifier est cliqué sur un postback, les données sont remontées à l’interface EditItemTemplated’édition, qui est responsable du rendu de l’interface d’édition. Cette interface inclut les contrôles Web pour modifier les données, ainsi que les boutons Mettre à jour et Annuler. La valeur par défaut EditItemTemplate générée par Visual Studio contient une étiquette pour tous les champs d’incrément automatique (ProductID), une zone de texte pour chaque champ de valeur non booléen et une case à cocher pour chaque champ de valeur booléenne. Ce comportement est très similaire aux champs BoundField générés automatiquement dans les contrôles GridView et DetailsView.

Remarque

Un petit problème avec la génération automatique de FormView est EditItemTemplate qu’il restitue les contrôles Web TextBox pour ces champs en lecture seule, tels que CategoryName et SupplierName. Nous allons voir comment tenir compte de cette situation sous peu.

Les contrôles TextBox dans la EditItemTemplate zone de texte ont leur Text propriété liée à la valeur de leur champ de données correspondant à l’aide de la liaison de données bidirectionnel. La liaison de données bidirectionnelle, indiquée par <%# Bind("dataField") %>, effectue la liaison de données lors de la liaison de données au modèle et lors du remplissage des paramètres de ObjectDataSource pour l’insertion ou la modification d’enregistrements. Autrement dit, lorsque l’utilisateur clique sur le bouton Modifier à partir du ItemTemplate, la Bind() méthode retourne la valeur de champ de données spécifiée. Une fois que l’utilisateur a apporté ses modifications et clique sur Mettre à jour, les valeurs publiées en retour correspondant aux champs de données spécifiés à l’aide Bind() UpdateParameterssont appliquées aux objets ObjectDataSource. Sinon, la liaison de données unidirectionnelle, indiquée par <%# Eval("dataField") %>, récupère uniquement les valeurs de champ de données lors de la liaison de données au modèle et ne retourne pas les valeurs entrées par l’utilisateur aux paramètres de la source de données lors de la publication.

Le balisage déclaratif suivant montre les éléments de FormView EditItemTemplate. Notez que la Bind() méthode est utilisée dans la syntaxe de liaison de données ici et que les contrôles Web Update et Cancel Button ont leurs CommandName propriétés définies en conséquence.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"> <EditItemTemplate> ProductID: <asp:Label ID="ProductIDLabel1" runat="server" Text="<%# Eval("ProductID") %>"></asp:Label><br /> ProductName: <asp:TextBox ID="ProductNameTextBox" runat="server" Text="<%# Bind("ProductName") %>"> </asp:TextBox><br /> SupplierID: <asp:TextBox ID="SupplierIDTextBox" runat="server" Text="<%# Bind("SupplierID") %>"> </asp:TextBox><br /> CategoryID: <asp:TextBox ID="CategoryIDTextBox" runat="server" Text="<%# Bind("CategoryID") %>"> </asp:TextBox><br /> QuantityPerUnit: <asp:TextBox ID="QuantityPerUnitTextBox" runat="server" Text="<%# Bind("QuantityPerUnit") %>"> </asp:TextBox><br /> UnitPrice: <asp:TextBox ID="UnitPriceTextBox" runat="server" Text="<%# Bind("UnitPrice") %>"> </asp:TextBox><br /> UnitsInStock: <asp:TextBox ID="UnitsInStockTextBox" runat="server" Text="<%# Bind("UnitsInStock") %>"> </asp:TextBox><br /> UnitsOnOrder: <asp:TextBox ID="UnitsOnOrderTextBox" runat="server" Text="<%# Bind("UnitsOnOrder") %>"> </asp:TextBox><br /> ReorderLevel: <asp:TextBox ID="ReorderLevelTextBox" runat="server" Text="<%# Bind("ReorderLevel") %>"> </asp:TextBox><br /> Discontinued: <asp:CheckBox ID="DiscontinuedCheckBox" runat="server" Checked="<%# Bind("Discontinued") %>" /><br /> CategoryName: <asp:TextBox ID="CategoryNameTextBox" runat="server" Text="<%# Bind("CategoryName") %>"> </asp:TextBox><br /> SupplierName: <asp:TextBox ID="SupplierNameTextBox" runat="server" Text="<%# Bind("SupplierName") %>"> </asp:TextBox><br /> <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update" Text="Update"> </asp:LinkButton> <asp:LinkButton ID="UpdateCancelButton" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"> </asp:LinkButton> </EditItemTemplate> <InsertItemTemplate> ... </InsertItemTemplate> <ItemTemplate> ... </ItemTemplate> </asp:FormView>

Notre EditItemTemplate, à ce stade, entraîne la levée d’une exception si nous essayons de l’utiliser. Le problème est que les champs et SupplierName les CategoryName champs sont rendus en tant que contrôles Web TextBox dans le EditItemTemplate. Nous devons soit modifier ces zones de texte en étiquettes, soit les supprimer complètement. Nous allons simplement les supprimer entièrement du EditItemTemplate.

La figure 23 montre formView dans un navigateur une fois que le bouton Modifier a été cliqué pour Chai. Notez que les champs et les SupplierName champs affichés dans le ItemTemplate fichier ne sont plus présents, car nous venons de les supprimer du EditItemTemplate.CategoryName Lorsque le bouton Mettre à jour est cliqué sur FormView passe par la même séquence d’étapes que les contrôles GridView et DetailsView.

Par défaut, l’élément EditItemTemplate affiche chaque champ de produit modifiable en tant que Zone de texte ou CheckBox

Figure 23 : Par défaut, le EditItemTemplate champ Afficher chaque champ produit modifiable sous forme de Zone de texte ou CheckBox (cliquez pour afficher l’image de taille complète)

Lorsque le bouton Insérer est cliqué sur le postback de ItemTemplate FormView, il en résulte. Toutefois, aucune donnée n’est liée à FormView, car un nouvel enregistrement est ajouté. L’interface InsertItemTemplate inclut les contrôles Web pour ajouter un nouvel enregistrement, ainsi que les boutons Insérer et Annuler. La valeur par défaut InsertItemTemplate générée par Visual Studio contient une zone de texte pour chaque champ de valeur non booléen et un CheckBox pour chaque champ de valeur booléenne, similaire à l’interface générée automatiquement EditItemTemplate. Les contrôles TextBox ont leur Text propriété liée à la valeur de leur champ de données correspondant à l’aide de la liaison de données bidirectionnel.

Le balisage déclaratif suivant montre les éléments de FormView InsertItemTemplate. Notez que la Bind() méthode est utilisée dans la syntaxe de liaison de données ici et que les contrôles Web Insert et Cancel Button ont leurs CommandName propriétés définies en conséquence.

<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"> <EditItemTemplate> ... </EditItemTemplate> <InsertItemTemplate> ProductName: <asp:TextBox ID="ProductNameTextBox" runat="server" Text="<%# Bind("ProductName") %>"> </asp:TextBox><br /> SupplierID: <asp:TextBox ID="SupplierIDTextBox" runat="server" Text="<%# Bind("SupplierID") %>"> </asp:TextBox><br /> CategoryID: <asp:TextBox ID="CategoryIDTextBox" runat="server" Text="<%# Bind("CategoryID") %>"> </asp:TextBox><br /> QuantityPerUnit: <asp:TextBox ID="QuantityPerUnitTextBox" runat="server" Text="<%# Bind("QuantityPerUnit") %>"> </asp:TextBox><br /> UnitPrice: <asp:TextBox ID="UnitPriceTextBox" runat="server" Text="<%# Bind("UnitPrice") %>"> </asp:TextBox><br /> UnitsInStock: <asp:TextBox ID="UnitsInStockTextBox" runat="server" Text="<%# Bind("UnitsInStock") %>"> </asp:TextBox><br /> UnitsOnOrder: <asp:TextBox ID="UnitsOnOrderTextBox" runat="server" Text="<%# Bind("UnitsOnOrder") %>"> </asp:TextBox><br /> ReorderLevel: <asp:TextBox ID="ReorderLevelTextBox" runat="server" Text="<%# Bind("ReorderLevel") %>"> </asp:TextBox><br /> Discontinued: <asp:CheckBox ID="DiscontinuedCheckBox" runat="server" Checked="<%# Bind("Discontinued") %>" /><br /> CategoryName: <asp:TextBox ID="CategoryNameTextBox" runat="server" Text="<%# Bind("CategoryName") %>"> </asp:TextBox><br /> SupplierName: <asp:TextBox ID="SupplierNameTextBox" runat="server" Text="<%# Bind("SupplierName") %>"> </asp:TextBox><br /> <asp:LinkButton ID="InsertButton" runat="server" CausesValidation="True" CommandName="Insert" Text="Insert"> </asp:LinkButton> <asp:LinkButton ID="InsertCancelButton" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"> </asp:LinkButton> </InsertItemTemplate> <ItemTemplate> ... </ItemTemplate> </asp:FormView>

Il y a une subtilité avec la génération automatique de FormView du InsertItemTemplate. Plus précisément, les contrôles Web TextBox sont créés même pour les champs en lecture seule, tels que CategoryName et SupplierName. Comme avec le EditItemTemplate, nous devons supprimer ces TextBoxes du InsertItemTemplate.

La figure 24 montre FormView dans un navigateur lors de l’ajout d’un nouveau produit, Acme Coffee. Notez que les SupplierName champs affichés CategoryName dans le fichier ItemTemplate ne sont plus présents, car nous venons de les supprimer. Lorsque le bouton Insérer est cliqué sur FormView, passez à la même séquence d’étapes que le contrôle DetailsView, en ajoutant un nouvel enregistrement à la Products table. La figure 25 montre les détails du produit Acme Coffee dans FormView une fois qu’il a été inséré.

InsertItemTemplate dicte l’interface d’insertion de FormView

Figure 24 : InsertItemTemplate Dicte l’interface d’insertion de FormView (cliquez pour afficher l’image de taille complète)

Les détails du nouveau produit, Acme Coffee, sont affichés dans FormView

Figure 25 : Les détails du nouveau produit, Acme Coffee, sont affichés dans FormView (cliquez pour afficher l’image pleine taille)

En séparant les interfaces en lecture seule, en modifiant et en insérant des interfaces dans trois modèles distincts, FormView permet un degré de contrôle plus fin sur ces interfaces que DetailsView et GridView.

Remarque

À l’instar de DetailsView, la propriété de CurrentMode FormView indique l’interface affichée et sa DefaultMode propriété indique le mode que FormView retourne une fois qu’une modification ou une insertion a été terminée.

Résumé

Dans ce tutoriel, nous avons examiné les principes fondamentaux de l’insertion, de la modification et de la suppression de données à l’aide de GridView, DetailsView et FormView. Ces trois contrôles fournissent un certain niveau de fonctionnalités de modification de données intégrées qui peuvent être utilisées sans écrire une seule ligne de code dans la page ASP.NET grâce aux contrôles Web de données et à ObjectDataSource. Toutefois, les techniques simples de point et de clic restituent une interface utilisateur de modification de données assez fragile et naïve. Pour fournir la validation, injectez des valeurs programmatiques, gérez correctement les exceptions, personnalisez l’interface utilisateur, et ainsi de suite, nous devons nous appuyer sur une envie de techniques qui seront abordées au cours des prochains tutoriels.

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 en tant que consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 en 24 heures. Il peut être accessible à mitchell@4GuysFromRolla.com. ou via son blog, qui peut être trouvé à http://ScottOnWriting.NET.