Partager via


Ajout d’une colonne GridView de boutons radio (VB)

par Scott Mitchell

Télécharger le PDF

Ce tutoriel explique comment ajouter une colonne de boutons radio à un contrôle GridView pour fournir à l’utilisateur un moyen plus intuitif de sélectionner une seule ligne de GridView.

Présentation

Le contrôle GridView offre une grande quantité de fonctionnalités intégrées. Il comprend plusieurs champs différents pour afficher du texte, des images, des liens hypertexte et des boutons. Il prend en charge les modèles pour une personnalisation supplémentaire. En quelques clics de la souris, il est possible de créer un GridView dans lequel chaque ligne peut être sélectionnée par le biais d’un bouton, ou pour activer la modification ou la suppression des fonctionnalités. Malgré la pléthore de fonctionnalités fournies, il y aura souvent des situations dans lesquelles des fonctionnalités supplémentaires non prises en charge devront être ajoutées. Dans ce tutoriel et les deux suivants, nous allons examiner comment améliorer les fonctionnalités de GridView pour inclure des fonctionnalités supplémentaires.

Ce tutoriel et le suivant se concentrent sur l’amélioration du processus de sélection de lignes. Comme nous l'avons examiné dans le Principal/Détail utilisant un GridView sélectionnable avec un DetailView, nous pouvons ajouter un Champ de commande au GridView qui inclut un bouton Sélectionner. Lorsque vous cliquez, un postback s'ensuit et la propriété GridView SelectedIndex est mise à jour avec l'index de la ligne dont le bouton Sélectionner a été cliqué. Dans le didacticiel Master/Detail Using a Selectable Master GridView with a Details DetailView, nous avons vu comment utiliser cette fonctionnalité pour afficher les détails de la ligne GridView sélectionnée.

Bien que le bouton Sélectionner fonctionne dans de nombreuses situations, il peut ne pas fonctionner aussi bien pour d’autres. Au lieu d’utiliser un bouton, deux autres éléments d’interface utilisateur sont couramment utilisés pour la sélection : la case d’option et la case à cocher. Nous pouvons augmenter GridView afin qu’au lieu d’un bouton Sélectionner, chaque ligne contient une case d’option ou une case à cocher. Dans les scénarios où l’utilisateur ne peut sélectionner qu’un des enregistrements GridView, le bouton radio peut être préféré au bouton Sélectionner. Dans les situations où l'utilisateur peut potentiellement sélectionner plusieurs enregistrements, comme dans une application de messagerie web, où un utilisateur peut souhaiter sélectionner plusieurs messages à supprimer, la case à cocher offre des fonctionnalités qui ne sont pas disponibles à partir du bouton Sélectionner ou des boutons radio.

Ce tutoriel explique comment ajouter une colonne de cases d’option à GridView. Le didacticiel de procédure explore l’utilisation de cases à cocher.

Étape 1 : Création des pages web améliorées pour GridView

Avant de commencer à améliorer GridView pour inclure une colonne de cases d’option, prenons d’abord un moment pour créer les pages ASP.NET dans notre projet de site web dont nous aurons besoin pour ce tutoriel et les deux suivantes. Commencez par ajouter un nouveau dossier nommé EnhancedGridView. Ensuite, ajoutez les ASP.NET pages suivantes à ce dossier, en veillant à associer chaque page à la Site.master page maître :

  • Default.aspx
  • RadioButtonField.aspx
  • CheckBoxField.aspx
  • InsertThroughFooter.aspx

Ajouter les pages ASP.NET pour les didacticiels SqlDataSource-Related

Figure 1 : Ajouter les pages de ASP.NET pour les didacticiels SqlDataSource-Related

Comme dans les autres dossiers, Default.aspx dans le EnhancedGridView 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 vers l’affichage Création de la page.

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

Figure 2 : Ajouter le contrôle utilisateur à SectionLevelTutorialListing.ascx (Default.aspx de taille complète)

Enfin, ajoutez ces quatre pages en tant qu’entrées au Web.sitemap fichier. Plus précisément, ajoutez le balisage suivant après l’utilisation du contrôle <siteMapNode>SqlDataSource :

<siteMapNode 
    title="Enhancing the GridView" 
    url="~/EnhancedGridView/Default.aspx" 
    description="Augment the user experience of the GridView control.">
    <siteMapNode 
        url="~/EnhancedGridView/RadioButtonField.aspx" 
        title="Selection via a Radio Button Column" 
        description="Explore how to add a column of radio buttons in the GridView." />
    <siteMapNode 
        url="~/EnhancedGridView/CheckBoxField.aspx" 
        title="Selection via a Checkbox Column" 
        description="Select multiple records in the GridView by using a column of 
            checkboxes." />
    <siteMapNode 
        url="~/EnhancedGridView/InsertThroughFooter.aspx" 
        title="Add New Records through the Footer" 
        description="Learn how to allow users to add new records through the 
            GridView's footer." />
</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 améliorer les didacticiels GridView

Figure 3 : La carte de site inclut désormais des entrées pour améliorer les didacticiels GridView

Étape 2 : affichage des fournisseurs dans un GridView

Pour ce tutoriel, nous allons créer un GridView qui répertorie les fournisseurs des États-Unis, avec chaque ligne GridView fournissant une case d’option. Après avoir sélectionné un fournisseur via la case d’option, l’utilisateur peut afficher les produits du fournisseur en cliquant sur un bouton. Bien que cette tâche puisse sembler triviale, il existe un certain nombre de subtilités qui le rendent particulièrement difficile. Avant de nous pencher sur ces subtilités, commençons par obtenir un GridView répertoriant les fournisseurs.

Commencez par ouvrir la RadioButtonField.aspx page dans le EnhancedGridView dossier en faisant glisser un GridView à partir de la boîte à outils vers le Concepteur. Définissez gridView s ID sur Suppliers et, à partir de sa balise active, choisissez de créer une source de données. Plus précisément, créez un ObjectDataSource nommé SuppliersDataSource qui extrait ses données de l’objet SuppliersBLL .

Créer un ObjectDataSource nommé SuppliersDataSource

Figure 4 : Créer un ObjetDataSource nommé SuppliersDataSource (cliquez pour afficher l’image de taille complète)

Capture d’écran de la fenêtre Configurer la source de données - SuppliersDataSource avec le menu déroulant Objet métier ouvert. FournisseursBLL est sélectionné et le bouton Suivant est mis en surbrillance.

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

Étant donné que nous voulons uniquement répertorier ces fournisseurs aux États-Unis, choisissez la GetSuppliersByCountry(country) méthode dans la liste déroulante sous l’onglet SELECT.

Capture d’écran de la fenêtre Configurer la source de données - SuppliersDataSource sous l’onglet SELECT avec le menu déroulant méthode ouverte. L’option de méthode GetSupplierByCountry est sélectionnée et le bouton Suivant est mis en surbrillance.

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

Sous l’onglet UPDATE, sélectionnez l’option (Aucun), puis cliquez sur Suivant.

Capture d’écran de la fenêtre Configurer la source de données - SuppliersDataSource sous l’onglet UPDATE avec le menu déroulant de méthode ouvert. L’option de méthode (None) est sélectionnée et le bouton Suivant est mis en surbrillance.

Figure 7 : Configurer ObjectDataSource pour utiliser la classe (SuppliersBLL de taille complète)

Étant donné que la GetSuppliersByCountry(country) méthode accepte un paramètre, l’Assistant Configuration de la source de données nous invite à entrer la source de ce paramètre. Pour spécifier une valeur codée en dur (États-Unis, dans cet exemple), laissez la liste déroulante Source du paramètre définie sur None et entrez la valeur par défaut dans la zone de texte. Cliquez sur Terminer pour finaliser l'Assistant.

Utiliser les États-Unis comme valeur par défaut pour le paramètre de pays

Figure 8 : Utiliser les États-Unis comme valeur par défaut pour le country paramètre (Cliquez pour afficher l’image de taille complète)

Une fois l’Assistant terminé, GridView inclut un Objet BoundField pour chacun des champs de données du fournisseur. Supprimez tout, mais CompanyNameles champs , Cityet Country BoundFields, puis renommez la CompanyName propriété BoundFields HeaderText en Fournisseur. Après cela, la syntaxe déclarative GridView et ObjectDataSource doit ressembler à ce qui suit.

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="CompanyName" HeaderText="Supplier" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliersByCountry" TypeName="SuppliersBLL">
    <SelectParameters>
        <asp:Parameter DefaultValue="USA" Name="country" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>

Pour ce tutoriel, permettez à l’utilisateur d’afficher les produits du fournisseur sélectionnés sur la même page que la liste des fournisseurs ou sur une autre page. Pour ce faire, ajoutez deux contrôles Web Button à la page. J'ai défini les ID de ces deux boutons à ListProducts et SendToProducts, avec l'idée que lorsqu'on clique sur ListProducts, un postback se produira et les produits du fournisseur sélectionné seront répertoriés sur la même page. Mais lorsque l'on clique sur SendToProducts, l'utilisateur sera redirigé vers une autre page qui répertorie les produits.

La figure 9 montre le GridView Suppliers et les deux contrôles Web Button lorsqu'ils sont affichés dans un navigateur.

Ces fournisseurs des États-Unis ont leur nom, leur ville et leurs informations de pays listées

Figure 9 : Les fournisseurs des États-Unis ont leur nom, leur ville et leurs informations sur le pays répertoriés (cliquez pour afficher l’image de taille complète)

Étape 3 : Ajout d’une colonne de cases d’option

À ce stade, Suppliers GridView a trois BoundFields affichant le nom de la société, la ville et le pays de chaque fournisseur aux États-Unis. Cependant, il manque toujours une colonne de cases d’option. Malheureusement, le GridView n’inclut pas de RadioButtonField intégré, sinon nous pourrions simplement l’ajouter à la grille et ce serait réglé. Au lieu de cela, nous pouvons ajouter un TemplateField et le configurer ItemTemplate pour afficher un bouton radio, ce qui produit un bouton radio pour chaque ligne du GridView.

Initialement, nous pouvons supposer que l’interface utilisateur souhaitée peut être implémentée en ajoutant un contrôle Web RadioButton à l’objet ItemTemplate TemplateField. Bien que cela ajoute en effet un bouton radio unique à chaque ligne de GridView, les boutons radio ne peuvent pas être regroupés et par conséquent, ne sont pas mutuellement exclusifs. Autrement dit, un utilisateur final peut sélectionner plusieurs boutons radio simultanément depuis GridView.

Même si l’utilisation d’un TemplateField de contrôles Web RadioButton n’offre pas les fonctionnalités dont nous avons besoin, nous allons implémenter cette approche, car il vaut la peine d’examiner pourquoi les boutons radio résultants ne sont pas regroupés. Commencez par ajouter un TemplateField à Suppliers GridView, ce qui en fait le champ le plus à gauche. Ensuite, à partir de la balise active gridView, cliquez sur le lien Modifier les modèles et faites glisser un contrôle Web RadioButton à partir de la boîte à outils dans templateField s ItemTemplate (voir la figure 10). Définissez la propriété ID du RadioButton sur RowSelector et la propriété GroupName sur SuppliersGroup.

Ajouter un contrôle Web RadioButton à ItemTemplate

Figure 10 : Ajouter un contrôle Web RadioButton à l’écran ItemTemplate (Cliquez pour afficher l’image de taille complète)

Après avoir effectué ces ajouts via le Concepteur, votre balisage GridView doit ressembler à ce qui suit :

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:RadioButton ID="RowSelector" runat="server" 
                    GroupName="SuppliersGroup" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="CompanyName" HeaderText="Supplier" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
    </Columns>
</asp:GridView>

La propriété RadioButton GroupName sert à regrouper une série de boutons radio. Tous les contrôles RadioButton avec la même valeur GroupName sont considérés comme regroupés ; un seul bouton radio peut être sélectionné dans un groupe à la fois. La propriété GroupName spécifie la valeur de l'attribut name du bouton radio rendu. Le navigateur examine les attributs name des cases d’option pour déterminer les regroupements de cases d’option.

Avec le contrôle Web RadioButton ajouté à la page ItemTemplate, visitez cette page via un navigateur et cliquez sur les boutons radio dans les lignes de la grille. Notez que les cases à cocher ne sont pas regroupées, ce qui permet la sélection de toutes les lignes, comme le montre la figure 11.

Les boutons radio de la GridView ne sont pas regroupés

Figure 11 : Les boutons radio de GridView ne sont pas regroupés (cliquez pour afficher l’image en taille réelle)

La raison pour laquelle les boutons radio ne sont pas regroupés est que leurs attributs rendus name sont différents, malgré le même paramètre de propriété GroupName. Pour voir ces différences, effectuez un Affichage/Source à partir du navigateur et examinez le balisage de bouton radio.

<input id="ctl00_MainContent_Suppliers_ctl02_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl02$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl03_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl03$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl04_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl04$SuppliersGroup" 
    type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl05_RowSelector" 
    name="ctl00$MainContent$Suppliers$ctl05$SuppliersGroup" 
    type="radio" value="RowSelector" />

Notez que les name valeurs et id attributs ne sont pas les valeurs exactes spécifiées dans la fenêtre Propriétés, mais qu’elles sont précédées d’un certain nombre d’autres ID valeurs. Les ID valeurs supplémentaires ajoutées à l'avant des attributs id et name rendus sont les ID des contrôles parents des cases d'option, les GridViewRow contrôles ID, les gridView ID, le content control ID et le Web Form ID. Ces ID éléments sont ajoutés pour que chaque contrôle Web rendu dans le GridView ait une valeur unique de id et name.

Chaque contrôle rendu a besoin d’identifiants distincts name et id car c’est ainsi que le navigateur identifie de manière unique chaque contrôle côté client et comment il informe le serveur web sur l'action ou la modification qui s’est produite lors du retour. Par exemple, imaginez que nous voulions exécuter du code côté serveur chaque fois qu’un état vérifié par RadioButton a été modifié. Pour ce faire, nous pouvons définir la propriété RadioButton AutoPostBack sur True et créer un gestionnaire d’événements pour l’événement CheckChanged. Toutefois, si les valeurs calculées de name et id pour tous les boutons radio étaient identiques, lors de l'envoi des données, nous ne pourrions pas déterminer quel bouton radio spécifique a été cliqué.

En bref, nous ne pouvons pas créer une colonne de boutons radio dans une vue grille à l’aide du contrôle Web RadioButton. Au lieu de cela, nous devons utiliser des techniques plutôt archaïques pour vous assurer que le balisage approprié est injecté dans chaque ligne GridView.

Remarque

Comme le contrôle Web RadioButton, le contrôle HTML de bouton radio, lorsqu’il est ajouté à un modèle, inclut l’attribut unique name, ce qui rend les boutons radio dans la grille non groupés. Si vous n’êtes pas familiarisé avec les contrôles HTML, n’hésitez pas à ignorer cette note, car les contrôles HTML sont rarement utilisés, en particulier dans ASP.NET 2.0. Mais si vous souhaitez en savoir plus, consultez l’entrée de blog de K. Scott Allensur les contrôles Web et les contrôles HTML.

Utilisation d’un contrôle littéral pour injecter le balisage de bouton radio

Pour regrouper correctement tous les boutons radio dans GridView, nous devons injecter manuellement le balisage des boutons radio dans le ItemTemplate. Chaque bouton radio a besoin du même attribut name, mais doit avoir un attribut unique id (si on veut accéder à un bouton radio via un script côté client). Une fois qu’un utilisateur sélectionne une case d’option et publie la page, le navigateur renvoie la valeur de l’attribut de la case d’option value sélectionnée. Par conséquent, chaque case d’option a besoin d’un attribut unique value . Enfin, lors de la soumission, nous devons nous assurer d’ajouter l’attribut checked au seul bouton radio sélectionné, sinon, une fois que l’utilisateur a effectué une sélection et renvoie le formulaire, les boutons radio reviendront à leur état par défaut (tous désélectionnés).

Il existe deux approches qui peuvent être prises pour injecter des marques de bas niveau dans un modèle. Il s’agit d’effectuer un mélange de balisage et d’appels aux méthodes de mise en forme définies dans la classe code-behind. Cette technique a d’abord été abordée dans l’utilisation de TemplateFields dans le didacticiel contrôle GridView . Dans notre cas, il peut ressembler à ceci :

<input type="radio" id='<%# GetUniqueRadioButtonID(...) %>' 
    name='SuppliersGroup' value='<%# GetRadioButtonValue(...) %>' ... />

Ici, GetUniqueRadioButton et GetRadioButtonValue seraient des méthodes définies dans la classe code-behind qui retourneraient les valeurs appropriées des attributs id et value pour chaque bouton radio. Cette approche fonctionne bien pour affecter les attributs id et value, mais elle montre ses limites lorsque vous avez besoin de spécifier la valeur de l'attribut checked, car la syntaxe de liaison des données est exécutée uniquement lorsque les données sont liées pour la première fois au GridView. Par conséquent, si l’état d’affichage du GridView est activé, les méthodes de mise en forme se déclenchent uniquement lorsque la page est chargée pour la première fois (ou lorsque le GridView est explicitement réassigné à la source de données), et par conséquent, la fonction qui définit l’attribut checked ne sera pas appelée lors de la publication. C’est un problème plutôt subtil et un peu au-delà de l’étendue de cet article, donc je vais le laisser à ce sujet. Toutefois, je vous encourage à essayer d’utiliser l’approche ci-dessus et de la travailler jusqu'à arriver au point de blocage. Bien qu’un tel exercice ne vous rapproche pas d’une version de travail, cela vous aidera à mieux comprendre le cycle de vie de GridView et la liaison de données.

L’autre approche pour injecter des marques personnalisées et de bas niveau dans un modèle et l’approche que nous allons utiliser pour ce didacticiel consiste à ajouter un contrôle littéral au modèle. Ensuite, dans le gestionnaire d’événements RowCreated ou RowDataBound de GridView, le contrôle littéral est accessible par programmation et sa Text propriété définie sur le balisage à émettre.

Commencez par supprimer le RadioBouton du TemplateField c0, en le remplaçant par le contrôle Literal. Définissez le contrôle littéral s ID à RadioButtonMarkup.

Ajouter un contrôle littéral à ItemTemplate

Figure 12 : Ajouter un contrôle littéral à l’image ItemTemplate (Cliquez pour afficher l’image de taille complète)

Ensuite, créez un gestionnaire d’événements pour l’événement RowCreated GridView. L’événement RowCreated se déclenche une fois pour chaque ligne ajoutée, que les données soient ou non en cours de rebond sur GridView. Cela signifie que même lors d'un retour de formulaire lorsque les données sont rechargées à partir de l'état d'affichage, l'événement RowCreated se déclenche toujours et c'est pourquoi nous l'utilisons au lieu de RowDataBound (qui se déclenche uniquement lorsque les données sont explicitement liées au contrôle Web des données).

Dans ce gestionnaire d’événements, nous voulons uniquement continuer si nous traitons une ligne de données. Pour chaque ligne de données, nous souhaitons programmer l'accès au contrôle RadioButtonMarkup Literal et attribuer sa propriété Text au balisage à émettre. Comme le montre le code suivant, le balisage émis crée une case d’option dont name l’attribut est défini SuppliersGroupsur , dont id l’attribut est défini RowSelectorXsur , où X est l’index de la ligne GridView et dont value l’attribut est défini sur l’index de la ligne GridView.

Protected Sub Suppliers_RowCreated(sender As Object, e As GridViewRowEventArgs) _
    Handles Suppliers.RowCreated
    
    If e.Row.RowType = DataControlRowType.DataRow Then
        ' Grab a reference to the Literal control
        Dim output As Literal = _
            CType(e.Row.FindControl("RadioButtonMarkup"), Literal)
        ' Output the markup except for the "checked" attribute
        output.Text = String.Format( _
            "<input type="radio" name="SuppliersGroup" " & _
            "id="RowSelector{0}" value="{0}" />", e.Row.RowIndex)
    End If
End Sub

Nous nous intéressons aux informations du fournisseur sélectionné lorsqu'une ligne GridView est sélectionnée et qu'un retour de formulaire se produit. Par conséquent, on peut penser que la valeur de chaque bouton radio doit correspondre à la valeur réelle SupplierID (plutôt qu’à l’index de la ligne GridView). Bien que cela puisse fonctionner dans certaines circonstances, il s’agirait d’un risque de sécurité pour accepter et traiter aveuglement un SupplierID. Notre GridView, par exemple, répertorie uniquement ces fournisseurs aux États-Unis. Toutefois, si la SupplierID case d’option est passée directement à partir de la case d’option, que s’agit-il d’empêcher un utilisateur malchanceux de manipuler la SupplierID valeur renvoyée à la publication ? En utilisant l'index de ligne comme value, puis en obtenant la SupplierID lors du postback depuis la collection DataKeys, nous pouvons garantir que l'utilisateur n'utilise qu'une des SupplierID valeurs associées à l'une des lignes du GridView.

Après avoir ajouté ce code de gestionnaire d’événements, prenez une minute pour tester la page dans un navigateur. Tout d’abord, notez qu’un seul bouton radio dans la grille peut être sélectionné à la fois. Toutefois, lors de la sélection d’un bouton radio et en cliquant sur l’un des boutons, une mise à jour de la page se produit et les boutons radio rétablissent toutes leur état initial (autrement dit, lors de la mise à jour, le bouton radio sélectionné n’est plus sélectionné). Pour résoudre ce problème, nous devons augmenter le RowCreated gestionnaire d’événements afin qu’il inspecte l’index de case d’option sélectionné envoyé à partir de la publication et ajoute l’attribut checked="checked" au balisage émis de l’index de ligne correspond.

Lorsqu’une réponse de formulaire se produit, le navigateur renvoie le name et le value du bouton radio sélectionné. La valeur peut être récupérée par programmation à l’aide Request.Form("name")de . La Request.Form propriété fournit un NameValueCollection représentant les variables de formulaire. Les variables de formulaire sont les noms et les valeurs des champs de formulaire dans la page web et sont renvoyées par le navigateur web chaque fois qu’un postback se produit. Étant donné que l’attribut rendu name des boutons radio dans GridView est SuppliersGroup, lorsque la page web est envoyée à nouveau, le navigateur renverra SuppliersGroup=valueOfSelectedRadioButton au serveur web ainsi que tous les autres champs de formulaires. Ces informations sont ensuite accessibles à partir de la propriété Request.Form en utilisant : Request.Form("SuppliersGroup").

Étant donné que nous devons déterminer l'index du bouton radio sélectionné non seulement dans le gestionnaire d'événements RowCreated, mais aussi dans ceux des contrôles Web Button Click, nous allons ajouter une propriété SuppliersSelectedIndex à la classe code-behind qui renvoie -1 si aucun bouton radio n'est sélectionné et l'index sélectionné si l'un des boutons radio est sélectionné.

Private ReadOnly Property SuppliersSelectedIndex() As Integer
    Get
        If String.IsNullOrEmpty(Request.Form("SuppliersGroup")) Then
            Return -1
        Else
            Return Convert.ToInt32(Request.Form("SuppliersGroup"))
        End If
    End Get
End Property

Avec cette propriété ajoutée, nous savons qu'il faut ajouter le balisage checked="checked" dans le gestionnaire d'événements RowCreated lorsque SuppliersSelectedIndex est égal à e.Row.RowIndex. Mettez à jour le gestionnaire d’événements pour inclure cette logique :

Protected Sub Suppliers_RowCreated(sender As Object, e As GridViewRowEventArgs) _
    Handles Suppliers.RowCreated
    
    If e.Row.RowType = DataControlRowType.DataRow Then
        ' Grab a reference to the Literal control
        Dim output As Literal = _
            CType(e.Row.FindControl("RadioButtonMarkup"), Literal)
        ' Output the markup except for the "checked" attribute
        output.Text = String.Format( _
            "<input type="radio" name="SuppliersGroup" " & _
            "id="RowSelector{0}" value="{0}"", e.Row.RowIndex)
        ' See if we need to add the "checked" attribute
        If SuppliersSelectedIndex = e.Row.RowIndex Then
            output.Text &= " checked="checked""
        End If
        ' Add the closing tag
        output.Text &= " />"
    End If
End Sub

Avec cette modification, le bouton radio sélectionné reste sélectionné après un retour au serveur. Maintenant que nous avons la possibilité de spécifier la case d’option sélectionnée, nous pourrions modifier le comportement afin que lorsque la page a été visitée pour la première fois, la première case d’option de la ligne GridView a été sélectionnée (au lieu d’avoir aucune case d’option sélectionnée par défaut, qui est le comportement actuel). Pour que la première case d’option soit sélectionnée par défaut, remplacez simplement l’instruction If SuppliersSelectedIndex = e.Row.RowIndex Then par la valeur suivante : If SuppliersSelectedIndex = e.Row.RowIndex OrElse (Not Page.IsPostBack AndAlso e.Row.RowIndex = 0) Then.

À ce stade, nous avons ajouté une colonne de boutons radio groupés au GridView qui permet à une seule ligne du GridView d’être sélectionnée et retenue à travers les postbacks. Nos étapes suivantes sont d’afficher les produits fournis par le fournisseur sélectionné. À l’étape 4, nous allons voir comment rediriger l’utilisateur vers une autre page, en envoyant l'élément sélectionné SupplierID. À l’étape 5, nous allons voir comment afficher les produits du fournisseur sélectionnés dans un GridView sur la même page.

Remarque

Au lieu d’utiliser un TemplateField (le focus de cette longue étape 3), nous pourrions créer une classe personnalisée DataControlField qui affiche l’interface utilisateur et la fonctionnalité appropriées. La DataControlField classe est la classe de base à partir de laquelle dérivent les champs BoundField, CheckBoxField, TemplateField et autres champs GridView et DetailsView intégrés. La création d’une classe personnalisée DataControlField signifie que la colonne de boutons radio peut être ajoutée simplement à l’aide de la syntaxe déclarative, et rend également la réplication des fonctionnalités sur d’autres pages web et d’autres applications web beaucoup plus facile.

Si vous avez créé des contrôles personnalisés et compilés dans ASP.NET, toutefois, vous savez que cela nécessite une bonne quantité de jambes et porte avec elle une multitude de subtilités et de cas de bord qui doivent être soigneusement gérés. Par conséquent, nous allons renoncer à implémenter une colonne de cases d’option sous forme de classe personnalisée DataControlField pour l’instant et nous en tenir à l’option TemplateField. Nous aurons peut-être la chance d’explorer la création, l’utilisation et le déploiement de classes personnalisées DataControlField dans un prochain tutoriel !

Étape 4 : Affichage des produits du fournisseur sélectionné dans une page distincte

Une fois que l’utilisateur a sélectionné une ligne GridView, nous devons afficher les produits du fournisseur sélectionnés. Dans certaines circonstances, nous souhaitons peut-être afficher ces produits dans une page distincte, dans d’autres, nous préférerons peut-être le faire dans la même page. Examinons tout d’abord comment afficher les produits dans une page distincte ; À l’étape 5, nous allons examiner l’ajout d’un GridView pour RadioButtonField.aspx afficher les produits du fournisseur sélectionnés.

Actuellement, il existe deux contrôles Web Button sur la page ListProducts et SendToProducts. Lorsque le SendToProducts bouton est cliqué, nous voulons envoyer l’utilisateur à ~/Filtering/ProductsForSupplierDetails.aspx. Cette page a été créée dans le didacticiel Master/Detail Filtering Across Two Pages et affiche les produits du fournisseur dont SupplierID le champ querystring est passé par le champ querystring nommé SupplierID.

Pour fournir cette fonctionnalité, créez un gestionnaire d’événements pour l’événement SendToProducts Button.Click À l’étape 3, nous avons ajouté la SuppliersSelectedIndex propriété, qui retourne l’index de la ligne dont la case d’option est sélectionnée. Les éléments correspondants SupplierID peuvent être récupérés à partir de la collection GridView DataKeys et l’utilisateur peut ensuite être envoyé à ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID l’aide Response.Redirect("url")de .

Protected Sub SendToProducts_Click(sender As Object, e As EventArgs) _
    Handles SendToProducts.Click
    
    ' Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
    Dim supplierID As Integer = _
        Convert.ToInt32(Suppliers.DataKeys(SuppliersSelectedIndex).Value)
    Response.Redirect( _
        "~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" & _
        supplierID)
End Sub

Ce code fonctionne merveilleusement tant que l’un des boutons radio est sélectionné à partir de GridView. Si, initialement, le GridView n’a pas de bouton radio sélectionné, et que l’utilisateur clique sur le bouton SendToProducts, SuppliersSelectedIndex sera -1, ce qui entraînera une exception, car -1 est hors de l'intervalle des indices de la collection DataKeys. Ce n'est pas un problème, toutefois, si vous avez décidé de mettre à jour le RowCreated gestionnaire d’événements comme indiqué à l’étape 3 afin d'avoir le premier bouton radio dans le GridView initialement sélectionné par défaut.

Pour accueillir une valeur de SuppliersSelectedIndex, ajoutez un contrôle Web Label à la page au-dessus du GridView. Définissez sa propriété ID sur ChooseSupplierMsg, sa propriété CssClass sur Warning, ses propriétés EnableViewState et Visible sur False, et sa propriété Text pour "Veuillez choisir un fournisseur dans la grille." La classe Warning CSS affiche du texte en rouge, italique, gras, grande police et est définie dans Styles.css. En définissant les propriétés EnableViewState et Visible à False, le label n'est pas rendu, excepté pour les seules réponses où la propriété du contrôle Visible est programmatiquement définie à True.

Ajouter un contrôle Web Label au-dessus de GridView

Figure 13 : Ajouter un contrôle Web Label au-dessus de GridView (Cliquez pour afficher l’image de taille complète)

Ensuite, augmentez le Click gestionnaire d’événements pour afficher l’étiquette ChooseSupplierMsg s’il SuppliersSelectedIndex est inférieur à zéro et redirigez l’utilisateur vers ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID le cas contraire.

Protected Sub SendToProducts_Click(sender As Object, e As EventArgs) _
    Handles SendToProducts.Click
    
    ' make sure one of the radio buttons has been selected
    If SuppliersSelectedIndex < 0 Then
        ChooseSupplierMsg.Visible = True
    Else
        ' Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
        Dim supplierID As Integer = _
            Convert.ToInt32(Suppliers.DataKeys(SuppliersSelectedIndex).Value)
        Response.Redirect( _
            "~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" & _
            supplierID)
    End If
End Sub

Visitez la page dans un navigateur et cliquez sur le SendToProducts bouton avant de sélectionner un fournisseur dans GridView. Comme le montre la figure 14, l'étiquette ChooseSupplierMsg s'affiche. Ensuite, sélectionnez un fournisseur, puis cliquez sur le SendToProducts bouton. Vous accédez ainsi à une page qui répertorie les produits fournis par le fournisseur sélectionné. La figure 15 montre la ProductsForSupplierDetails.aspx page où le fournisseur Bigfoot Breweries a été sélectionné.

L’étiquette ChooseSupplierMsg s’affiche si aucun fournisseur n’est sélectionné

Figure 14 : L’étiquette ChooseSupplierMsg s’affiche si aucun fournisseur n’est sélectionné (cliquez pour afficher l’image de taille complète)

Les produits fournisseurs sélectionnés sont affichés dans ProductsForSupplierDetails.aspx

Figure 15 : Les produits fournisseurs sélectionnés sont affichés dans ProductsForSupplierDetails.aspx (Cliquez pour afficher l’image de taille complète)

Étape 5 : Affichage des produits du fournisseur sélectionnés sur la même page

À l’étape 4, nous avons vu comment envoyer l’utilisateur à une autre page web pour afficher les produits du fournisseur sélectionnés. Vous pouvez également afficher les produits du fournisseur sélectionnés sur la même page. Pour illustrer cela, nous allons ajouter un autre GridView à RadioButtonField.aspx pour afficher les produits sélectionnés du fournisseur.

Étant donné que nous souhaitons que ce GridView de produits ne s'affiche qu'après la sélection d'un fournisseur, ajoutez un contrôle Web Panel sous le GridView Suppliers, en définissant sa propriété ID sur ProductsBySupplierPanel et sa propriété Visible sur False. Dans le panneau, ajoutez le texte Produits pour le fournisseur sélectionné, suivi d’un GridView nommé ProductsBySupplier. À partir de la balise intelligente GridView, choisissez de la lier à un nouvel ObjectDataSource nommé ProductsBySupplierDataSource.

Lier la GridView ProductsBySupplier à un nouvel ObjectDataSource

Figure 16 : Lier ProductsBySupplier GridView à un Nouvel ObjectDataSource (Cliquez pour afficher l’image de taille complète)

Ensuite, configurez ObjectDataSource pour utiliser la ProductsBLL classe. Étant donné que nous voulons uniquement récupérer ces produits fournis par le fournisseur sélectionné, spécifiez que ObjectDataSource doit appeler la GetProductsBySupplierID(supplierID) méthode pour récupérer ses données. Sélectionnez (Aucun) dans les listes déroulantes sous les onglets UPDATE, INSERT et DELETE.

Configurer ObjectDataSource pour utiliser la méthode GetProductsBySupplierID(supplierID)

Figure 17 : Configurer ObjectDataSource pour utiliser la méthode (GetProductsBySupplierID(supplierID) de taille complète)

Définissez les listes Drop-Down sur (Aucun) dans les onglets UPDATE, INSERT et DELETE

Figure 18 : Définir les listes Drop-Down sur (Aucun) dans les onglets UPDATE, INSERT et DELETE (cliquez pour afficher l’image de taille complète)

Après avoir configuré les onglets SELECT, UPDATE, INSERT et DELETE, cliquez sur Suivant. Étant donné que la méthode GetProductsBySupplierID(supplierID) attend un paramètre d’entrée, l’assistant de création de source de données nous invite à spécifier la source de la valeur du paramètre.

Nous avons quelques options ici pour spécifier la source de la valeur du paramètre. Nous pourrions utiliser l’objet Parameter par défaut et affecter par programmation la valeur de la propriété à la SuppliersSelectedIndex propriété Parameter DefaultValue dans le gestionnaire d’événements ObjectDataSource.Selecting Reportez-vous au didacticiel Affectation des valeurs des paramètres de ObjectDataSource par programmation pour revoir l’affectation de valeurs par programmation aux paramètres d'ObjectDataSource.

Vous pouvez également utiliser un ControlParameter pour faire référence à la propriété de Suppliers GridView SelectedValue (voir la figure 19). La propriété GridView SelectedValue retourne la DataKey valeur correspondant à la SelectedIndex propriété. Pour que cette option fonctionne, nous devons définir par programmation la propriété GridView SelectedIndex sur la ligne sélectionnée lorsque le ListProducts bouton est cliqué. En guise d’avantage supplémentaire, en définissant SelectedIndex, l’enregistrement sélectionné adoptera l’SelectedRowStyle défini dans la DataWebControls Thème (avec un arrière-plan jaune).

Utiliser un ControlParameter pour spécifier la valeur selectedValue de GridView en tant que source de paramètre

Figure 19 : Utiliser un ControlParameter pour spécifier la valeur sélectionnée de GridView en tant que source de paramètre (cliquez pour afficher l’image de taille complète)

Une fois l’Assistant terminé, Visual Studio ajoute automatiquement des champs pour les champs de données du produit. Supprimez tous les éléments sauf les BoundFields ProductName, CategoryName, et UnitPrice, et modifiez les propriétés HeaderText en Product, Category, et Price. UnitPrice Configurez BoundField afin que sa valeur soit mise en forme en tant que devise. Après avoir apporté ces modifications, le balisage déclaratif du Panneau, gridView et ObjectDataSource doit ressembler à ce qui suit :

<asp:Panel runat="server" ID="ProductsBySupplierPanel" Visible="False">
    <h3>
        Products for the Selected Supplier</h3>
    <p>
        <asp:GridView ID="ProductsBySupplier" runat="server" 
            AutoGenerateColumns="False" DataKeyNames="ProductID"
            DataSourceID="ProductsBySupplierDataSource" EnableViewState="False">
            <Columns>
                <asp:BoundField DataField="ProductName" HeaderText="Product" 
                    SortExpression="ProductName" />
                <asp:BoundField DataField="CategoryName" HeaderText="Category" 
                    ReadOnly="True" SortExpression="CategoryName" />
                <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" 
                    HeaderText="Price" HtmlEncode="False" 
                    SortExpression="UnitPrice" />
            </Columns>
        </asp:GridView>
        <asp:ObjectDataSource ID="ProductsBySupplierDataSource" runat="server" 
            OldValuesParameterFormatString="original_{0}"
            SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
            <SelectParameters>
                <asp:ControlParameter ControlID="Suppliers" Name="supplierID" 
                    PropertyName="SelectedValue" Type="Int32" />
            </SelectParameters>
        </asp:ObjectDataSource>
    </p>
</asp:Panel>

Pour effectuer cet exercice, nous devons définir la propriété SelectedIndex du GridView sur SelectedSuppliersIndex et la propriété ProductsBySupplierPanel du panneau Visible sur True lorsque le bouton ListProducts est cliqué. Pour ce faire, créez un gestionnaire d’événements pour l’événement ListProducts du contrôle Web de type Button Click et ajoutez le code suivant :

Protected Sub ListProducts_Click(sender As Object, e As EventArgs) _
    Handles ListProducts.Click
    
    ' make sure one of the radio buttons has been selected
    If SuppliersSelectedIndex < 0 Then
        ChooseSupplierMsg.Visible = True
        ProductsBySupplierPanel.Visible = False
    Else
        ' Set the GridView's SelectedIndex
        Suppliers.SelectedIndex = SuppliersSelectedIndex
        ' Show the ProductsBySupplierPanel panel
        ProductsBySupplierPanel.Visible = True
    End If
End Sub

Si un fournisseur n’a pas été sélectionné dans GridView, l’étiquette ChooseSupplierMsg est affichée et le ProductsBySupplierPanel panneau masqué. Sinon, si un fournisseur a été sélectionné, il ProductsBySupplierPanel s’affiche et la propriété GridView SelectedIndex est mise à jour.

La figure 20 montre les résultats après la sélection du fournisseur Bigfoot Breweries et le bouton Afficher les produits sur la page a été cliqué.

Les produits fournis par Bigfoot Breweries sont répertoriés sur la même page

Figure 20 : Les produits fournis par Bigfoot Breweries sont répertoriés sur la même page (cliquez pour afficher l’image pleine taille)

Résumé

Comme indiqué dans le didacticiel Master/Detail Using a Selectable Master GridView with a Details DetailView, les enregistrements peuvent être sélectionnés à partir d'un GridView à l'aide d'un CommandField dont la ShowSelectButton propriété est définie True sur. Mais CommandField affiche ses boutons sous forme de boutons push, de liens ou d’images standard. Une autre interface utilisateur de sélection de lignes consiste à fournir une case d’option ou une case à cocher dans chaque ligne de "GridView". Dans ce tutoriel, nous avons examiné comment ajouter une colonne de boutons radio.

Malheureusement, l’ajout d’une colonne de boutons radio n’est pas aussi évident ou simple que l’on pourrait s’y attendre. Il n’existe aucun RadioButtonField intégré qui peut être ajouté au clic d’un bouton, et l’utilisation du contrôle Web RadioButton dans un TemplateField introduit son propre ensemble de problèmes. En fin de compte, pour fournir une telle interface, nous devons créer une classe personnalisée DataControlField ou recourir à injecter le code HTML approprié dans un TemplateField pendant l’événement RowCreated .

Après avoir exploré comment ajouter une colonne de cases d’option, laissez-nous attirer notre attention sur l’ajout d’une colonne de cases à cocher. Avec une colonne de cases à cocher, un utilisateur peut sélectionner une ou plusieurs lignes GridView, puis effectuer une opération sur toutes les lignes sélectionnées (par exemple, sélectionner un ensemble d’e-mails à partir d’un client de messagerie web, puis choisir de supprimer tous les e-mails sélectionnés). Dans le tutoriel suivant, nous allons voir comment ajouter une telle colonne.

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. On peut le joindre à mitchell@4GuysFromRolla.com.

Merci spécial à

Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. Le réviseur principal de ce tutoriel était David Suru. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.