Vue d’ensemble de l’insertion, de la mise à jour et de la suppression de données (VB)
par Scott Mitchell
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).
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
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.
Figure 3 : Ajouter le contrôle utilisateur à Default.aspx
(Cliquez pour afficher l’image SectionLevelTutorialListing.ascx
de 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.
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.
Figure 5 : Configurer ObjectDataSource pour utiliser la classe (Cliquez pour afficher l’image ProductsBLL
de 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.
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 AddProduct
de UpdateProduct
la ProductsBLL
classe.
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)
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)
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
, UpdateParameters
et InsertParameters
qui mappent aux paramètres d’entrée pour les méthodes et DeleteProduct
les méthodes de AddProduct
UpdateProduct
la 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 DeleteParameters
valeurs UpdateParameters
sont 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
ProductID
champs etSupplierName
lesCategoryName
champs sont marqués comme étant en lecture seule et ne doivent donc pas être mis à jour lors de laProductsDataTable
modification. Pour ce faire, ces propriétés ReadOnly de BoundFields sont définiesTrue
sur . - 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 :
- La ou les valeurs de ObjectDataSource
DeleteParameters
sont affectées - La méthode ObjectDataSource est appelée, en supprimant l’enregistrement
Delete()
spécifié - 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é false
GridView 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.
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.
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.
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.
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]
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 :
- La propriété gridView est affectée à l’index
EditItemIndex
de la ligne dont le bouton Modifier a été cliqué - GridView se connecte à ObjectDataSource en appelant sa
Select()
méthode - 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 dontReadOnly
les propriétés sont False (valeur par défaut) sont affichées en tant que contrôles Web TextBox dontText
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 :
- 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. - La méthode ObjectDataSource est appelée, mettant à jour l’enregistrement
Update()
spécifié - 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.
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é True
sur . 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.
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
ouSupplierID
qui n’existe pas dans la base de données, ilUPDATE
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 laUnitPrice
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 laUnitPrice
UpdateParameters
valeur, ce qui modifierait l’enregistrement de base deUnitPrice
données en valeurNULL
. De même, si un champ obligatoire, tel queProductName
, 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, lesCategoryID
valeurs contiennentSupplierID
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.
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.
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 False
sur . Prenez un moment pour définir les propriétés False
de 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.
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.
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.
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
, Insert
ou 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
, InsertItemTemplate
et 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 New
sur , Edit
et 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.
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 EditItemTemplate
d’é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()
UpdateParameters
sont 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.
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é.
Figure 24 : InsertItemTemplate
Dicte l’interface d’insertion de FormView (cliquez pour afficher l’image de taille complète)
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.