Utilisation de TemplateFields dans le contrôle DetailsView (C#)
par Scott Mitchell
Les mêmes fonctionnalités TemplateFields disponibles avec GridView sont également disponibles avec le contrôle DetailsView. Dans ce tutoriel, nous allons afficher un produit à la fois à l’aide d’un DetailsView contenant TemplateFields.
Introduction
TemplateField offre un degré de flexibilité plus élevé dans le rendu des données que les contrôles BoundField, CheckBoxField, HyperLinkField et d’autres contrôles de champ de données. Dans le tutoriel précédent, nous avons examiné l’utilisation de TemplateField dans un GridView pour :
- Afficher plusieurs valeurs de champ de données dans une colonne. Plus précisément, les champs et
LastName
lesFirstName
champs ont été combinés en une seule colonne GridView. - Utilisez un autre contrôle Web pour exprimer une valeur de champ de données. Nous avons vu comment afficher la valeur à l’aide
HiredDate
d’un contrôle Calendar. - Afficher les informations d’état en fonction des données sous-jacentes. Bien que la
Employees
table ne contienne pas de colonne qui retourne le nombre de jours pendant lesquels un employé a été sur le travail, nous avons pu afficher ces informations dans l’exemple GridView dans le didacticiel précédent avec l’utilisation d’une méthode TemplateField et de mise en forme.
Les mêmes fonctionnalités TemplateFields disponibles avec GridView sont également disponibles avec le contrôle DetailsView. Dans ce tutoriel, nous allons afficher un produit à la fois à l’aide d’un DetailsView qui contient deux TemplateFields. Le premier TemplateField combine les champs de UnitsInStock
données et UnitsOnOrder
les UnitPrice
champs de données en une seule ligne DetailsView. Le deuxième TemplateField affiche la valeur du champ, mais utilise une méthode de Discontinued
mise en forme pour afficher « OUI » si Discontinued
c’est true
le cas et « NON » dans le cas contraire.
Figure 1 : Deux TemplateFields sont utilisés pour personnaliser l’affichage (cliquez pour afficher l’image de taille complète)
C’est parti !
Étape 1 : Liaison des données au DetailsView
Comme indiqué dans le tutoriel précédent, lors de l’utilisation de TemplateFields, il est souvent plus simple de commencer par créer le contrôle DetailsView qui contient uniquement BoundFields, puis ajouter de nouveaux TemplateFields ou convertir les champs BoundFields existants en TemplateFields selon les besoins. Par conséquent, démarrez ce didacticiel en ajoutant un DetailsView à la page via le Concepteur et en le liant à un ObjectDataSource qui retourne la liste des produits. Ces étapes créent un DetailsView avec BoundFields pour chacun des champs de valeur non booléens du produit et un CheckBoxField pour le champ valeur booléenne (supprimé).
Ouvrez la DetailsViewTemplateField.aspx
page et faites glisser un DetailsView à partir de la boîte à outils sur le Concepteur. Dans la balise active DetailsView, choisissez d’ajouter un nouveau contrôle ObjectDataSource qui appelle la méthode de GetProducts()
la ProductsBLL
classe.
Figure 2 : Ajouter un nouveau contrôle ObjectDataSource qui appelle la GetProducts()
méthode (Click pour afficher l’image de taille complète)
Pour ce rapport, supprimez les ProductID
champs , SupplierID
et CategoryID
ReorderLevel
BoundFields. Ensuite, réorganisez les BoundFields afin que les CategoryName
champs SupplierName
et les champs de liaison apparaissent immédiatement après boundField ProductName
. N’hésitez pas à ajuster les propriétés et les HeaderText
propriétés de mise en forme pour boundFields comme vous le voyez. Comme avec GridView, ces modifications au niveau de BoundField peuvent être effectuées via la boîte de dialogue Champs (accessible en cliquant sur le lien Modifier les champs dans la balise active de DetailsView) ou via la syntaxe déclarative. Enfin, désactivez les valeurs de propriété et Width
de Height
DetailsView pour autoriser le contrôle DetailsView à développer en fonction des données affichées et cochez la case Activer la pagination dans la balise active.
Après avoir apporté ces modifications, le balisage déclaratif de votre contrôle DetailsView doit ressembler à ce qui suit :
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="Units In Stock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="Units On Order" SortExpression="UnitsOnOrder" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
Prenez un moment pour afficher la page via un navigateur. À ce stade, vous devriez voir un seul produit répertorié (Chai) avec des lignes indiquant le nom, la catégorie, le fournisseur, le prix, les unités en stock, les unités sur commande et son état abandonné.
Figure 3 : Les détails du produit sont affichés à l’aide d’une série de BoundFields (cliquez pour afficher l’image de taille complète)
Étape 2 : combinaison du prix, des unités en stock et des unités sur commande en une seule ligne
DetailsView a une ligne pour les champs et UnitsOnOrder
les UnitPrice
UnitsInStock
champs. Nous pouvons combiner ces champs de données en une seule ligne avec un TemplateField en ajoutant un nouveau TemplateField ou en convertissant l’un des champs de données existants UnitPrice
UnitsInStock
, et UnitsOnOrder
BoundFields en un TemplateField. Bien que je préfère personnellement convertir des BoundFields existants, nous allons nous exercer en ajoutant un nouveau TemplateField.
Commencez par cliquer sur le lien Modifier les champs dans la balise active detailsView pour afficher la boîte de dialogue Champs. Ensuite, ajoutez un nouveau TemplateField et définissez sa HeaderText
propriété sur « Price and Inventory » et déplacez le nouveau TemplateField afin qu’il soit positionné au-dessus de UnitPrice
BoundField.
Figure 4 : Ajouter un nouveau templateField au contrôle DetailsView (Cliquez pour afficher l’image de taille complète)
Étant donné que ce nouveau TemplateField contiendra les valeurs actuellement affichées dans les UnitPrice
champs UnitsInStock
, et UnitsOnOrder
BoundFields, nous allons les supprimer.
La dernière tâche de cette étape consiste à définir le ItemTemplate
balisage du ModèleField de prix et d’inventaire, qui peut être effectué via l’interface de modification de modèle de DetailsView dans le Concepteur ou manuellement par le biais de la syntaxe déclarative du contrôle. Comme avec GridView, l’interface de modification de modèle de DetailsView est accessible en cliquant sur le lien Modifier les modèles dans la balise active. À partir de là, vous pouvez sélectionner le modèle à modifier dans la liste déroulante, puis ajouter des contrôles Web à partir de la boîte à outils.
Pour ce tutoriel, commencez par ajouter un contrôle Label aux champs Price et Inventory TemplateField ItemTemplate
. Ensuite, cliquez sur le lien Modifier dataBindings à partir de la balise active du contrôle Web Label et liez la Text
propriété au UnitPrice
champ.
Figure 5 : Lier la propriété de Text
l’étiquette au UnitPrice
champ de données (cliquez pour afficher l’image de taille complète)
Mise en forme du prix en tant que devise
Avec cet ajout, le Prix du contrôle Web d’étiquette et Inventory TemplateField affiche désormais uniquement le prix du produit sélectionné. La figure 6 montre une capture d’écran de notre progression jusqu’à présent lorsqu’elle est consultée via un navigateur.
Figure 6 : Price and Inventory TemplateField Affiche le prix (Cliquez pour afficher l’image de taille complète)
Notez que le prix du produit n’est pas mis en forme comme devise. Avec un BoundField, la mise en forme est possible en définissant la HtmlEncode
propriété sur false
et la DataFormatString
propriété {0:formatSpecifier}
sur . Pour un TemplateField, toutefois, toutes les instructions de mise en forme doivent être spécifiées dans la syntaxe de liaison de données ou à l’aide d’une méthode de mise en forme définie quelque part dans le code de l’application (par exemple, dans la classe code-behind de la page ASP.NET).
Pour spécifier la mise en forme de la syntaxe de liaison de données utilisée dans le contrôle Web Label, revenez à la boîte de dialogue DataBindings en cliquant sur le lien Modifier dataBindings à partir de la balise active de l’étiquette. Vous pouvez taper les instructions de mise en forme directement dans la liste déroulante Format ou sélectionner l’une des chaînes de format définies. Comme avec la propriété BoundField DataFormatString
, la mise en forme est spécifiée à l’aide {0:formatSpecifier}
de .
Pour le UnitPrice
champ, utilisez la mise en forme monétaire spécifiée en sélectionnant la valeur de liste déroulante appropriée ou en tapant {0:C}
manuellement.
Figure 7 : Mettre en forme le prix sous forme de devise (cliquez pour afficher l’image de taille complète)
De manière déclarative, la spécification de mise en forme est indiquée en tant que deuxième paramètre dans les méthodes ou Eval
les Bind
méthodes. Les paramètres simplement effectués via le Concepteur entraînent l’expression de liaison de données suivante dans le balisage déclaratif :
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>
Ajout des champs de données restants à TemplateField
À ce stade, nous avons affiché et mis en forme le UnitPrice
champ de données dans price and Inventory TemplateField, mais nous devons toujours afficher les champs et UnitsOnOrder
les UnitsInStock
champs. Affichons-les sur une ligne sous le prix et entre parenthèses. À partir de l’interface de modification de modèle dans le Concepteur, ce balisage peut être ajouté en positionnant votre curseur dans le modèle et en tapant simplement le texte à afficher. Vous pouvez également entrer ce balisage directement dans la syntaxe déclarative.
Ajoutez le balisage statique, les contrôles Web Label et la syntaxe de liaison de données afin que price and Inventory TemplateField affiche les informations de prix et d’inventaire comme suit :
UnitPrice
(En stock / En commande : UnitsInStock / UnitsOnOrder)
Après avoir effectué cette tâche, le balisage déclaratif de DetailsView doit ressembler à ce qui suit :
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="Product" SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:TemplateField HeaderText="Price and Inventory">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:Label>
<br />
<strong>
(In Stock / On Order: </strong>
<asp:Label ID="Label2" runat="server"
Text='<%# Eval("UnitsInStock") %>'></asp:Label>
<strong>/</strong>
<asp:Label ID="Label3" runat="server"
Text='<%# Eval("UnitsOnOrder") %>'>
</asp:Label><strong>)</strong>
</ItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
Avec ces modifications, nous avons consolidé les informations de prix et d’inventaire dans une seule ligne DetailsView.
Figure 8 : Les informations sur le prix et l’inventaire sont affichées dans une seule ligne (cliquez pour afficher l’image de taille complète)
Étape 3 : Personnalisation des informations de champ abandonnées
La Products
colonne de la Discontinued
table est une valeur de bits qui indique si le produit a été supprimé. Lors de la liaison d’un DetailsView (ou GridView) à un contrôle de source de données, les champs de valeur booléenne, tels Discontinued
que , sont implémentés en tant que CheckBoxFields, tandis que les champs de valeur non booléens, tels que ProductID
, ProductName
et ainsi de suite, sont implémentés en tant que BoundFields. CheckBoxField s’affiche sous la forme d’une case à cocher désactivée qui est cochée si la valeur du champ de données est True et décochée dans le cas contraire.
Au lieu d’afficher le CheckBoxField, nous pouvons plutôt afficher le texte indiquant si le produit est supprimé ou non. Pour ce faire, nous pourrions supprimer CheckBoxField de DetailsView, puis ajouter un BoundField dont DataField
la propriété a été définie Discontinued
sur . Prenez un moment pour le faire. Après cette modification, DetailsView affiche le texte « True » pour les produits supprimés et « False » pour les produits qui sont toujours actifs.
Figure 9 : Les chaînes True et False sont utilisées pour afficher l’état abandonné (cliquez pour afficher l’image de taille complète)
Imaginez que nous ne voulions pas que les chaînes « True » ou « False » soient utilisées, mais « OUI » et « NON », à la place. Cette personnalisation peut être effectuée à l’aide d’un TemplateField et d’une méthode de mise en forme. Une méthode de mise en forme peut prendre n’importe quel nombre de paramètres d’entrée, mais doit retourner le code HTML (sous forme de chaîne) à injecter dans le modèle.
Ajoutez une méthode de mise en forme à la classe code-behind de la DetailsViewTemplateField.aspx
page nommée DisplayDiscontinuedAsYESorNO
qui accepte un booléen comme paramètre d’entrée et retourne une chaîne. Comme indiqué dans le didacticiel précédent, cette méthode doit être marquée comme protected
ou public
pour être accessible à partir du modèle.
protected string DisplayDiscontinuedAsYESorNO(bool discontinued)
{
if (discontinued)
return "YES";
else
return "NO";
}
Cette méthode vérifie le paramètre d’entrée (discontinued
) et retourne « YES » s’il s’agit true
de « NO » sinon.
Remarque
Dans la méthode de mise en forme examinée dans le tutoriel précédent, rappelez-vous que nous transmettions un champ de données qui peut contenir NULL
, et donc nécessaire pour vérifier si la valeur de propriété de HiredDate
l’employé avait une valeur de base de données NULL
avant d’accéder à la EmployeesRow
propriété de l’employé HiredDate
. Cette vérification n’est pas nécessaire ici, car la Discontinued
colonne ne peut jamais avoir de valeurs de base de données NULL
affectées. En outre, c’est pourquoi la méthode peut accepter un paramètre d’entrée booléen plutôt que d’avoir à accepter une ProductsRow
instance ou un paramètre de type object
.
Avec cette méthode de mise en forme terminée, tout ce qui reste est de l’appeler ItemTemplate
à partir du ModèleField. Pour créer TemplateField, supprimez BoundField Discontinued
et ajoutez un nouveau TemplateField ou convertissez-le Discontinued
en un TemplateField. Ensuite, à partir de l’affichage de balisage déclaratif, modifiez TemplateField afin qu’il contienne uniquement un ItemTemplate qui appelle la DisplayDiscontinuedAsYESorNO
méthode, en passant la valeur de la propriété de l’instance Discontinued
actuelleProductRow
. Vous pouvez y accéder via la Eval
méthode. Plus précisément, le balisage de TemplateField doit ressembler à ceci :
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<%# DisplayDiscontinuedAsYESorNO((bool)
Eval("Discontinued")) %>
</ItemTemplate>
</asp:TemplateField>
Cela entraîne l’appel de la DisplayDiscontinuedAsYESorNO
méthode lors du rendu de DetailsView, en passant la valeur de l’instance ProductRow
Discontinued
. Étant donné que la Eval
méthode retourne une valeur de type object
, mais que la DisplayDiscontinuedAsYESorNO
méthode attend un paramètre d’entrée de type bool
, nous cassons la valeur bool
renvoyée par les Eval
méthodes . La DisplayDiscontinuedAsYESorNO
méthode retourne ensuite « YES » ou « NO » en fonction de la valeur qu’elle reçoit. La valeur retournée est ce qui est affiché dans cette ligne DetailsView (voir la figure 10).
Figure 10 : Les valeurs OUI ou NON sont désormais affichées dans la ligne abandonnée (cliquez pour afficher l’image de taille complète)
Résumé
Le ModèleField dans le contrôle DetailsView permet un degré de flexibilité plus élevé dans l’affichage des données qu’avec les autres contrôles de champ et est idéal pour les situations où :
- Plusieurs champs de données doivent être affichés dans une colonne GridView
- Les données sont mieux exprimées à l’aide d’un contrôle Web plutôt que de texte brut
- La sortie dépend des données sous-jacentes, telles que l’affichage des métadonnées ou la reformatage des données
Bien que TemplateFields autorise un plus grand degré de flexibilité dans le rendu des données sous-jacentes de DetailsView, la sortie DetailsView se sent toujours un peu boxy, car chaque champ est rendu sous forme de ligne dans un code HTML <table>
.
Le contrôle FormView offre un plus grand degré de flexibilité dans la configuration de la sortie rendue. FormView ne contient pas de champs, mais plutôt une série de modèles (ItemTemplate
, EditItemTemplate
, HeaderTemplate
etc.). Nous verrons comment utiliser FormView pour mieux contrôler la disposition rendue dans notre prochain tutoriel.
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.
Merci spécial à
Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. Le réviseur principal de ce didacticiel était Dan Jagers. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.