Partager via


Ajout d’une colonne GridView de cases d’option (VB)

par Scott Mitchell

Télécharger le PDF

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

Introduction

Le contrôle GridView offre de nombreuses fonctionnalités intégrées. Il comprend un certain nombre de 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 via un bouton, ou d’activer les fonctionnalités de modification ou de suppression. Malgré la pléthore de fonctionnalités fournies, il arrive souvent que des fonctionnalités supplémentaires non prises en charge soient 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 Master /Detail À l’aide d’un GridView maître sélectionnable avec un Details DetailView, nous pouvons ajouter un Champ de commandes au GridView qui comprend un bouton Sélectionner. Lorsque vous cliquez dessus, une publication s’ensuit et la propriété GridView est SelectedIndex mise à jour vers 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 DetailsView , 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 personnes. 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 le GridView afin qu’au lieu d’un bouton Sélectionner, chaque ligne contienne une case d’option ou une case à cocher. Dans les scénarios où l’utilisateur ne peut sélectionner qu’un seul des enregistrements GridView, la case d’option peut être préférée au bouton Sélectionner. Dans les situations où l’utilisateur peut potentiellement sélectionner plusieurs enregistrements, par exemple dans une application de messagerie web, où un utilisateur peut souhaiter sélectionner plusieurs messages pour supprimer la case à cocher offre des fonctionnalités qui ne sont pas disponibles à partir du bouton Sélectionner ou des interfaces utilisateur de case d’option.

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

Étape 1 : Création des pages web GridView

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

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

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

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

Comme dans les autres dossiers, Default.aspx dans le EnhancedGridView dossier répertoriera les tutoriels dans sa section. Rappelez-vous que le SectionLevelTutorialListing.ascx contrôle utilisateur fournit cette fonctionnalité. Par conséquent, ajoutez ce contrôle utilisateur à Default.aspx en le faisant glisser du Explorateur de solutions vers le mode Création de la page.

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

Figure 2 : Ajouter le SectionLevelTutorialListing.ascx contrôle utilisateur à Default.aspx (Cliquer pour afficher l’image en taille réelle)

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 tutoriels via un navigateur. Le menu de gauche inclut désormais des éléments pour la modification, l’insertion et la suppression des didacticiels.

Le plan de site inclut désormais des entrées pour l’amélioration des tutoriels GridView

Figure 3 : Le plan de site inclut désormais des entrées pour l’amélioration des 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, 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 la rendent particulièrement délicate. Avant de nous pencher sur ces subtilités, nous allons d’abord obtenir un GridView répertoriant les fournisseurs.

Commencez par ouvrir la RadioButtonField.aspx page dans le EnhancedGridView dossier en faisant glisser un GridView de la boîte à outils vers le Designer. Définissez GridView sur IDSuppliers 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 objetDataSource nommé SuppliersDataSource

Figure 4 : Créer un objetDataSource nommé SuppliersDataSource (cliquer pour afficher l’image en taille réelle)

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

Figure 5 : Configurer ObjectDataSource pour utiliser la SuppliersBLL classe (cliquer pour afficher l’image en taille réelle)

Étant donné que nous voulons uniquement répertorier ces fournisseurs aux États-Unis, choisissez la GetSuppliersByCountry(country) méthode dans la liste déroulante de 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 ouvert. 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 SuppliersBLL classe (cliquer pour afficher l’image en taille réelle)

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 méthode ouvert. L’option de méthode (Aucun) est sélectionnée et le bouton Suivant est mis en surbrillance.

Figure 7 : Configurer ObjectDataSource pour utiliser la SuppliersBLL classe (cliquer pour afficher l’image en taille réelle)

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

Utiliser USA comme valeur par défaut pour le paramètre de pays

Figure 8 : Utiliser USA comme valeur par défaut pour le country paramètre (cliquer pour afficher l’image en taille réelle)

Une fois l’Assistant terminé, GridView inclut un objet BoundField pour chacun des champs de données du fournisseur. Supprimez tous les CompanyNameéléments sauf , Cityet Country BoundFields, et 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 des fournisseurs 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 Button Web à la page. J’ai défini les ID s de ces deux boutons sur ListProducts et SendToProducts, avec l’idée que quand ListProducts est cliqué une publication se produira et les produits du fournisseur sélectionné seront répertoriés sur la même page, mais quand SendToProducts est cliqué, l’utilisateur sera redirigé vers une autre page qui répertorie les produits.

La figure 9 montre les Suppliers contrôles GridView et les deux contrôles Web Button lorsqu’ils sont consultés via un navigateur.

Ces fournisseurs des États-Unis ont leur nom, leur ville et leur pays indiqués

Figure 9 : Les fournisseurs des États-Unis ont leur nom, leur ville et leur pays répertoriés (cliquer pour afficher l’image en taille réelle)

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

À ce stade, le Suppliers GridView a trois boundFields qui affichent le nom de l’entreprise, la ville et le pays de chaque fournisseur aux États-Unis. Il manque toujours une colonne de cases d’option, cependant. Malheureusement, le GridView n’inclut pas de RadioButtonField intégré, sinon nous pourrions simplement ajouter cela à la grille et être fait. Au lieu de cela, nous pouvons ajouter un TemplateField et configurer son ItemTemplate pour afficher une case d’option, ce qui entraîne une case d’option pour chaque ligne GridView.

Initialement, nous pouvons supposer que l’interface utilisateur souhaitée peut être implémentée en ajoutant un contrôle Web RadioButton au ItemTemplate d’un TemplateField. Bien que cela ajoute en effet une case d’option unique à chaque ligne du GridView, les cases d’option ne peuvent pas être regroupées et ne sont donc pas mutuellement exclusives. Autrement dit, un utilisateur final peut sélectionner plusieurs cases d’option simultanément à partir de GridView.

Même si l’utilisation d’un champ de modèles de contrôles Web RadioButton n’offre pas les fonctionnalités dont nous avons besoin, implémentons cette approche, car il est utile d’examiner pourquoi les cases d’option obtenues ne sont pas regroupées. Commencez par ajouter un TemplateField au GridView fournisseurs, 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 vers templateField ( ItemTemplate voir figure 10). Définissez la propriété RadioButton sur ID et la GroupName propriété sur SuppliersGroup.RowSelector

Ajouter un contrôle Web RadioButton à ItemTemplate

Figure 10 : Ajouter un contrôle Web RadioButton à (ItemTemplateCliquer pour afficher l’image en taille réelle)

Après avoir effectué ces ajouts via le Designer, 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 s GroupName est utilisée pour regrouper une série de cases d’option. Tous les contrôles RadioButton ayant la même GroupName valeur sont considérés comme groupés ; une seule case d’option peut être sélectionnée à partir d’un groupe à la fois. La GroupName propriété spécifie la valeur de l’attribut s de la case d’option name rendue. Le navigateur examine les attributs des name cases d’option pour déterminer les regroupements de cases d’option.

Avec le contrôle RadioButton Web ajouté à , ItemTemplateaccédez à cette page via un navigateur et cliquez sur les cases d’option dans les lignes de la grille. Notez que les cases d’option ne sont pas regroupées, ce qui permet de sélectionner toutes les lignes, comme le montre la figure 11.

Les cases d’option de GridView ne sont pas regroupées

Figure 11 : Les cases d’option de GridView ne sont pas regroupées (cliquer pour afficher l’image en taille réelle)

La raison pour laquelle les cases d’option ne sont pas regroupées est que leurs attributs rendus name sont différents, bien qu’ayant le même GroupName paramètre de propriété. Pour voir ces différences, effectuez une vue/source à partir du navigateur et examinez le balisage de la case d’option :

<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 attributs et id ne sont pas les valeurs exactes spécifiées dans le Fenêtre Propriétés, mais sont ajoutés à un certain nombre d’autres ID valeurs. Les valeurs supplémentaires ID ajoutées à l’avant du rendu id et name des attributs sont les ID s des cases d’option parent contrôle les GridViewRow s ID , les GridView s ID, les contrôles content s IDet web Form s ID. Ces ID valeurs sont ajoutées afin que chaque contrôle Web rendu dans GridView ait une valeur et name uniqueid.

Chaque contrôle rendu a besoin d’un contrôle différent name , id car c’est ainsi que le navigateur identifie de manière unique chaque contrôle côté client et comment il identifie au serveur web l’action ou la modification qui s’est produite lors de la publication. Par exemple, imaginez que nous voulions exécuter du code côté serveur chaque fois qu’un état de vérification de RadioButton a été modifié. Pour ce faire, nous pouvons définir la propriété RadioButton sur AutoPostBack et créer un gestionnaire d’événements pour l’événementCheckChanged.True Toutefois, si le rendu name et id les valeurs de toutes les cases d’option étaient identiques, lors de la publication, nous n’avons pas pu déterminer sur quel radioButton spécifique a été cliqué.

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

Notes

Comme le contrôle Web RadioButton, le contrôle HTML de case d’option, lorsqu’il est ajouté à un modèle, inclut l’attribut unique name , ce qui permet de dissocier les cases d’option de la grille. 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 Allencontrôles web et contrôles HTML.

Utilisation d’un contrôle littéral pour injecter le balisage de case d’option

Pour regrouper correctement toutes les cases d’option dans GridView, nous devons injecter manuellement le balisage des cases d’option dans le ItemTemplate. Chaque case d’option a besoin du même name attribut, mais doit avoir un attribut unique id (si nous voulons accéder à une case d’option 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é. Par conséquent, chaque case d’option a besoin d’un attribut unique value . Enfin, lors de la publication, nous devons nous assurer d’ajouter l’attribut checked à la case d’option sélectionnée. Dans le cas contraire, une fois que l’utilisateur a fait une sélection et a retranscrit, les cases d’option retournent à leur état par défaut (toutes non sélectionnées).

Il existe deux approches qui peuvent être prises pour injecter un balisage de bas niveau dans un modèle. L’une consiste à 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 été décrite pour la première fois dans le didacticiel Utilisation de TemplateFields dans le contrôle GridView . Dans notre cas, cela 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 a retourné les valeurs appropriées id et value d’attribut pour chaque case d’option. Cette approche fonctionne bien pour l’affectation id des attributs et value , mais elle est limitée lorsque vous devez spécifier la valeur de l’attribut checked , car la syntaxe de liaison de données n’est exécutée que lorsque les données sont liées pour la première fois à GridView. Par conséquent, si l’état d’affichage de 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 redirigé vers la source de données), et par conséquent, la fonction qui définit l’attribut checked n’est pas appelée lors de la publication. C’est un problème assez subtil et un peu au-delà de la portée de cet article, donc je vais le laisser à ceci. Toutefois, je vous encourage à essayer d’utiliser l’approche ci-dessus et à la travailler jusqu’au point où vous serez bloqué. Bien qu’un tel exercice ne vous rapproche pas d’une version opérationnelle, il vous aidera à mieux comprendre gridView et le cycle de vie de la liaison de données.

L’autre approche pour injecter un balisage personnalisé 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 GridView, RowDataBound le contrôle Literal peut être accessible par programmation et sa Text propriété est définie sur le balisage à émettre.

Commencez par supprimer le RadioButton du TemplateField, ItemTemplateen le remplaçant par un contrôle Literal. Définissez le contrôle Littéral s ID sur RadioButtonMarkup.

Ajouter un contrôle littéral à ItemTemplate

Figure 12 : Ajouter un contrôle littéral à (ItemTemplateCliquer pour afficher l’image en taille réelle)

Ensuite, créez un gestionnaire d’événements pour l’événement GridView RowCreated . 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 dans GridView. Cela signifie que même sur une publication lorsque les données sont rechargées à partir de l’état d’affichage, l’événement RowCreated se déclenche toujours et c’est la raison pour laquelle nous l’utilisons à la place de RowDataBound (qui se déclenche uniquement lorsque les données sont explicitement liées au contrôle Web de 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 voulons référencer par programmation le RadioButtonMarkup contrôle Literal et définir sa Text propriété sur le balisage à émettre. Comme le montre le code suivant, le balisage émis crée une case d’option dont name l’attribut est défini sur SuppliersGroup, dont id l’attribut est défini sur RowSelectorX, 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

Lorsqu’une ligne GridView est sélectionnée et qu’une publication se produit, nous nous intéressons au SupplierID fournisseur sélectionné. Par conséquent, on peut penser que la valeur de chaque case d’option doit être la valeur réelle SupplierID (plutôt que l’index de la ligne GridView). Bien que cela puisse fonctionner dans certaines circonstances, il serait risqué pour la sécurité d’accepter et de traiter aveuglément un SupplierID. Notre GridView, par exemple, répertorie uniquement les fournisseurs aux États-Unis. Toutefois, si le SupplierID est transmis directement à partir de la case d’option, qu’est-ce qui empêche un utilisateur malicieux de manipuler la SupplierID valeur renvoyée lors de la publication ? En utilisant l’index de ligne comme value, puis en obtenant le SupplierID sur publication de la DataKeys collection, nous pouvons nous assurer que l’utilisateur n’utilise qu’une des SupplierID valeurs associées à l’une des lignes 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’une seule case d’option dans la grille peut être sélectionnée à la fois. Toutefois, lorsque vous sélectionnez une case d’option et que vous cliquez sur l’un des boutons, une publication se produit et les cases d’option reviennent toutes à leur état initial (autrement dit, lors de la publication, la case d’option sélectionnée n’est plus sélectionnée). 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 des correspondances d’index de ligne.

Lorsqu’une publication se produit, le navigateur renvoie et namevalue de la case d’option sélectionnée. La valeur peut être récupérée par programmation à l’aide de Request.Form("name"). 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’une publication est effectuée. Étant donné que l’attribut rendu name des cases d’option dans GridView est SuppliersGroup, lorsque la page web est publiée, le navigateur renvoie SuppliersGroup=valueOfSelectedRadioButton au serveur web (avec les autres champs de formulaire). Ces informations sont ensuite accessibles à partir de la propriété à l’aide Request.Form de : Request.Form("SuppliersGroup").

Étant donné que nous devons déterminer l’index de case d’option sélectionné non seulement dans le RowCreated gestionnaire d’événements, mais aussi dans les Click gestionnaires d’événements pour les contrôles Button Web, nous allons ajouter une SuppliersSelectedIndex propriété à la classe code-behind qui retourne -1 si aucune case d’option n’a été sélectionnée et l’index sélectionné si l’une des cases d’option est sélectionnée.

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

Une fois cette propriété ajoutée, nous savons e.Row.RowIndexqu’il faut ajouter le checked="checked" balisage dans le RowCreated gestionnaire d’événements quand SuppliersSelectedIndex est égal à . 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, la case d’option sélectionnée reste sélectionnée après une publication. Maintenant que nous avons la possibilité de spécifier la case d’option sélectionnée, nous pouvons modifier le comportement afin que, lors de la première visite de la page, la première case d’option de ligne GridView ait été sélectionnée (au lieu d’avoir aucune case d’option sélectionnée par défaut, ce 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 cases d’option groupées à GridView qui permet de sélectionner et de mémoriser une seule ligne GridView dans les publications. Les é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 le long du sélectionné SupplierID. À l’étape 5, nous verrons comment afficher les produits du fournisseur sélectionnés dans un GridView sur la même page.

Notes

Au lieu d’utiliser un TemplateField (le focus de cette longue étape 3), nous pourrions créer une classe personnalisée DataControlField qui restitue l’interface utilisateur et les fonctionnalités 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 cases d’option peut être ajoutée simplement à l’aide de la syntaxe déclarative, et facilite considérablement la réplication des fonctionnalités sur d’autres pages web et d’autres applications web.

Si vous avez déjà créé des contrôles compilés personnalisés dans ASP.NET, toutefois, vous savez que cela nécessite une bonne quantité de travail et comporte une multitude de subtilités et de cas de bord qui doivent être gérés avec soin. Par conséquent, nous allons renoncer à implémenter une colonne de cases d’option en tant que classe personnalisée DataControlField pour l’instant et nous nous en tenir à l’option TemplateField. Nous aurons peut-être la possibilité 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és 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 pouvons souhaiter afficher ces produits dans une page distincte, dans d’autres, nous préférerons le faire dans la même page. Examinons d’abord comment afficher les produits dans une page distincte ; À l’étape 5, nous allons examiner l’ajout d’un GridView à RadioButtonField.aspx pour afficher les produits du fournisseur sélectionné.

Il existe actuellement deux contrôles Button Web sur la page ListProducts et SendToProducts. Lorsque vous cliquez sur le SendToProducts bouton, 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 de chaîne de requête 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. Le correspondant SupplierID peut être récupéré à partir de la collection GridView DataKeys et l’utilisateur peut ensuite être envoyé à l’aide Response.Redirect("url")de ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID .

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 parfaitement tant que l’une des cases d’option est sélectionnée dans GridView. Si, initialement, gridView n’a pas de cases d’option sélectionnées et que l’utilisateur clique sur le SendToProducts bouton, SuppliersSelectedIndex est -1, ce qui entraîne la levée d’une exception, car -1 est en dehors de la plage d’index de la DataKeys collection. Toutefois, ce n’est pas un problème si vous avez décidé de mettre à jour le RowCreated gestionnaire d’événements comme indiqué à l’étape 3 afin que la première case d’option de GridView soit initialement sélectionnée.

Pour prendre en compte la SuppliersSelectedIndex valeur -1, ajoutez un contrôle Label Web à la page au-dessus de GridView. Définissez sa ID propriété sur ChooseSupplierMsg, sa CssClass propriété sur Warning, ses EnableViewState propriétés Falseet Visible sur , et sa Text propriété sur Veuillez choisir un fournisseur dans la grille. La classe Warning CSS affiche le texte dans une police rouge, italique, gras et volumineuse et est définie dans Styles.css. En définissant les EnableViewState propriétés Falseet Visible sur , l’étiquette n’est pas rendue, sauf pour les publications postback où la propriété du Visible contrôle est définie par programmation sur True.

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

Figure 13 : Ajouter un contrôle Web Label au-dessus du GridView (cliquer pour afficher l’image en taille réelle)

Ensuite, augmentez le Click gestionnaire d’événements pour afficher l’étiquette ChooseSupplierMsg si SuppliersSelectedIndex est inférieure à 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 est ChooseSupplierMsg affichée. Ensuite, sélectionnez un fournisseur, puis cliquez sur le SendToProducts bouton . Vous accédez alors à 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 en taille réelle)

Les produits du fournisseur sélectionnés sont affichés dans ProductsForSupplierDetails.aspx

Figure 15 : Les produits du fournisseur sélectionnés sont affichés dans ProductsForSupplierDetails.aspx (Cliquer pour afficher l’image en taille réelle)

É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é. 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 du fournisseur sélectionné.

Étant donné que nous voulons que ce GridView de produits s’affiche uniquement une fois qu’un fournisseur a été sélectionné, ajoutez un contrôle Web Panel sous gridViewSuppliers, en définissant sa IDProductsBySupplierPanel propriété Falsesur et sur Visible . Dans le panneau, ajoutez le texte Products pour le fournisseur sélectionné, suivi d’un GridView nommé ProductsBySupplier. À partir de la balise active gridView, choisissez de la lier à un nouvel ObjetDataSource nommé ProductsBySupplierDataSource.

Lier le GridView ProductsBySupplier à un nouvel objetDataSource

Figure 16 : Lier gridView ProductsBySupplier à un nouvel objetDataSource (cliquer pour afficher l’image en taille réelle)

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

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

Figure 17 : Configurer objectDataSource pour utiliser la GetProductsBySupplierID(supplierID) méthode (cliquer pour afficher l’image en taille réelle)

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

Figure 18 : Définissez le Drop-Down Listes sur (Aucun) dans les onglets UPDATE, INSERT et DELETE (Cliquez pour afficher l’image en taille réelle)

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

Nous avons deux options ici pour spécifier la source de la valeur s du paramètre. Nous pouvons utiliser l’objet Parameter par défaut et affecter par programmation la valeur de la SuppliersSelectedIndex propriété à la propriété Parameter dans DefaultValue le gestionnaire d’événements Selecting ObjectDataSource. Reportez-vous au didacticiel Définition par programmation des valeurs de paramètre d’ObjectDataSource pour obtenir un rappel sur l’affectation par programmation de valeurs aux paramètres d’ObjectDataSource.

Vous pouvez également utiliser un ControlParameter et faire référence à la Suppliers propriété 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 vous cliquez sur le ListProducts bouton. En outre, en définissant le SelectedIndex, l’enregistrement sélectionné prend le SelectedRowStyle défini dans le DataWebControls thème (arrière-plan jaune).

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

Figure 19 : Utiliser un paramètre ControlParameter pour spécifier la valeur sélectionnée gridView comme source du paramètre (cliquez pour afficher l’image de taille réelle)

Une fois l’Assistant terminé, Visual Studio ajoute automatiquement des champs pour les champs de données du produit. Supprimez tous les ProductNamechamps sauf , CategoryNameet UnitPrice BoundFields, puis remplacez les HeaderText propriétés par Product, Category et Price. Configurez l’objet UnitPrice BoundField afin que sa valeur soit mise en forme en tant que devise. Après avoir apporté ces modifications, le balisage déclaratif de Panel, 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é GridView SelectedIndex sur et SelectedSuppliersIndex la ProductsBySupplierPanel propriété Panel Visible sur True lorsque vous cliquez sur le ListProducts bouton. Pour ce faire, créez un gestionnaire d’événements pour l’événement ListProducts de contrôle Web 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 aucun fournisseur n’a été sélectionné dans gridView, l’étiquette ChooseSupplierMsg s’affiche et le ProductsBySupplierPanel panneau est masqué. Sinon, si un fournisseur a été sélectionné, le ProductsBySupplierPanel s’affiche et la propriété GridView est SelectedIndex mise à jour.

La figure 20 montre les résultats après que le fournisseur Bigfoot Breweries a été sélectionné et que l’utilisateur a cliqué sur le bouton Afficher les produits sur la page.

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 en taille réelle)

Résumé

Comme indiqué dans le didacticiel Master/Detail Using a Selectable Master GridView with a DetailsView , records can be selected from a GridView using a CommandField dont ShowSelectButton la propriété a la Truevaleur . Toutefois, le Champ de commande affiche ses boutons sous forme de boutons push, de liens ou d’images standard. Une autre interface utilisateur de sélection de ligne consiste à fournir une case d’option ou une case à cocher dans chaque ligne GridView. Dans ce tutoriel, nous avons examiné comment ajouter une colonne de cases d’option.

Malheureusement, l’ajout d’une colonne de cases d’option n’est pas aussi simple ou aussi simple que prévu. Il n’y a pas de RadioButtonField intégré qui peut être ajouté en un clic, 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 soit créer une classe personnalisée DataControlField , soit recourir à l’injection du code HTML approprié dans un TemplateField pendant l’événement RowCreated .

Après avoir exploré comment ajouter une colonne de cases d’option, nous allons nous intéresser à 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 comme consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Il est accessible à l’adressemitchell@4GuysFromRolla.com . ou via son blog, qui se trouve à l’adresse http://ScottOnWriting.NET.

Remerciements spéciaux à

Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. 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.