Hinzufügen einer GridView-Spalte mit Optionsfeldern (VB)
von Scott Mitchell
In diesem Tutorial wird erläutert, wie Sie einem GridView-Steuerelement eine Spalte mit Optionsfeldern hinzufügen, um dem Benutzer eine intuitivere Möglichkeit zu bieten, eine einzelne Zeile der GridView auszuwählen.
Einführung
Das GridView-Steuerelement bietet viele integrierte Funktionen. Es enthält eine Reihe von verschiedenen Feldern zum Anzeigen von Text, Bildern, Hyperlinks und Schaltflächen. Es unterstützt Vorlagen für weitere Anpassungen. Mit wenigen Mausklicks ist es möglich, eine GridView zu erstellen, in der jede Zeile über eine Schaltfläche ausgewählt werden kann, oder um Bearbeitungs- oder Löschfunktionen zu aktivieren. Trotz der Fülle der bereitgestellten Features müssen häufig zusätzliche, nicht unterstützte Features hinzugefügt werden. In diesem Tutorial und den beiden nächsten Lernprogramm erfahren Sie, wie Sie die GridView-Funktionalität um zusätzliche Features erweitern können.
Dieses und das nächste Tutorial konzentrieren sich auf die Verbesserung des Zeilenauswahlprozesses. Wie in master /detail Using a Selectable Master GridView with a Details DetailView untersucht, können wir der GridView ein CommandField hinzufügen, das eine Schaltfläche Auswählen enthält. Wenn Sie darauf geklickt haben, wird ein Postback ausgeführt, und die GridView-Eigenschaft SelectedIndex
wird in den Index der Zeile aktualisiert, auf deren Schaltfläche Auswählen geklickt wurde. Im Tutorial Master/Detail Using a Selectable Master GridView with a Details DetailView (Master/Detail Using a Selectable Master GridView with a Details DetailView) (Master/Detail Using a Selectable Master GridView with a Detail DetailView) (Master/Detail Using a Selectable Master GridView with a Details DetailView) haben wir erfahren, wie Sie dieses Feature verwenden, um Details für die ausgewählte GridView-Zeile anzuzeigen.
Während die Schaltfläche Auswählen in vielen Situationen funktioniert, funktioniert sie möglicherweise nicht so gut für andere. Anstatt eine Schaltfläche zu verwenden, werden häufig zwei weitere Benutzeroberflächenelemente für die Auswahl verwendet: das Optionsfeld und das Kontrollkästchen. Wir können die GridView erweitern, sodass anstelle einer Schaltfläche Auswählen jede Zeile ein Optionsfeld oder ein Kontrollkästchen enthält. In Szenarien, in denen der Benutzer nur einen der GridView-Datensätze auswählen kann, ist das Optionsfeld möglicherweise der Schaltfläche Auswählen vorzuziehen. In Situationen, in denen der Benutzer möglicherweise mehrere Datensätze auswählen kann, z. B. in einer webbasierten E-Mail-Anwendung, in denen ein Benutzer möglicherweise mehrere Nachrichten zum Löschen auswählen möchte, bietet das Kontrollkästchen Funktionen, die nicht über die Schaltfläche Auswählen oder die Optionsfeldbenutzeroberflächen verfügbar sind.
In diesem Tutorial wird erläutert, wie Sie der GridView eine Spalte mit Optionsfeldern hinzufügen. Das weitere Tutorial untersucht die Verwendung von Kontrollkästchen.
Schritt 1: Erstellen der Erweiterung der GridView-Webseiten
Bevor wir mit der Erweiterung von GridView beginnen, um eine Spalte mit Optionsfeldern einzuschließen, nehmen wir uns zunächst einen Moment Zeit, um die ASP.NET Seiten in unserem Websiteprojekt zu erstellen, die wir für dieses Tutorial und die nächsten beiden benötigen. Beginnen Sie mit dem Hinzufügen eines neuen Ordners mit dem Namen EnhancedGridView
. Fügen Sie als Nächstes die folgenden ASP.NET Seiten zu diesem Ordner hinzu, und stellen Sie sicher, dass jede Seite der Site.master
master Seite zugeordnet wird:
Default.aspx
RadioButtonField.aspx
CheckBoxField.aspx
InsertThroughFooter.aspx
Abbildung 1: Hinzufügen der ASP.NET Seiten für die SqlDataSource-Related Tutorials
Wie in den anderen Ordnern Default.aspx
werden im EnhancedGridView
Ordner die Tutorials in seinem Abschnitt aufgelistet. Denken Sie daran, dass das SectionLevelTutorialListing.ascx
Benutzersteuerelement diese Funktionalität bereitstellt. Fügen Sie daher dieses Benutzersteuerelement hinzuDefault.aspx
, indem Sie es aus dem Projektmappen-Explorer auf die Entwurfsansicht der Seite ziehen.
Abbildung 2: Hinzufügen des SectionLevelTutorialListing.ascx
Benutzersteuerelements zu Default.aspx
(Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Fügen Sie schließlich diese vier Seiten als Einträge zur Web.sitemap
Datei hinzu. Fügen Sie insbesondere das folgende Markup nach dem Verwenden des SqlDataSource-Steuerelements <siteMapNode>
hinzu:
<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>
Nehmen Sie sich nach dem Aktualisieren Web.sitemap
einen Moment Zeit, um die Tutorials-Website über einen Browser anzuzeigen. Das Menü auf der linken Seite enthält jetzt Elemente zum Bearbeiten, Einfügen und Löschen von Tutorials.
Abbildung 3: Die Siteübersicht enthält jetzt Einträge zum Verbessern der GridView-Tutorials
Schritt 2: Anzeigen der Lieferanten in einer GridView
In diesem Tutorial können Sie eine GridView erstellen, die die Lieferanten aus den USA auflistet, wobei jede GridView-Zeile ein Optionsfeld bereitstellt. Nach der Auswahl eines Lieferanten über das Optionsfeld kann der Benutzer die Produkte des Lieferanten anzeigen, indem er auf eine Schaltfläche klickt. Obwohl diese Aufgabe trivial klingt, gibt es eine Reihe von Feinheiten, die sie besonders schwierig machen. Bevor wir uns mit diesen Feinheiten befassen, sollten wir zunächst eine GridView-Liste mit den Lieferanten erhalten.
Öffnen Sie zunächst die RadioButtonField.aspx
Seite im EnhancedGridView
Ordner, indem Sie eine GridView aus der Toolbox auf die Designer ziehen. Legen Sie die GridView s ID
auf fest Suppliers
, und wählen Sie über das Smarttag eine neue Datenquelle aus. Erstellen Sie insbesondere eine ObjectDataSource mit dem Namen SuppliersDataSource
, die ihre Daten aus dem SuppliersBLL
-Objekt abruft.
Abbildung 4: Erstellen eines neuen ObjektsDataSource namens SuppliersDataSource
(Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Abbildung 5: Konfigurieren der ObjectDataSource für die Verwendung der SuppliersBLL
-Klasse (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Da wir nur diese Lieferanten in den USA auflisten möchten, wählen Sie die GetSuppliersByCountry(country)
Methode aus der Dropdownliste auf der Registerkarte SELECT aus.
Abbildung 6: Konfigurieren der ObjectDataSource für die Verwendung der SuppliersBLL
-Klasse (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Wählen Sie auf der Registerkarte UPDATE die Option (Keine) aus, und klicken Sie auf Weiter.
Abbildung 7: Konfigurieren der ObjectDataSource für die Verwendung der SuppliersBLL
-Klasse (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Da die GetSuppliersByCountry(country)
-Methode einen Parameter akzeptiert, fordert uns der Assistent Datenquelle konfigurieren zur Angabe der Quelle dieses Parameters auf. Wenn Sie einen hartcodierten Wert angeben möchten ( USA, in diesem Beispiel), lassen Sie die Dropdownliste Parameterquelle auf Keine festgelegt, und geben Sie den Standardwert in das Textfeld ein. Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen.
Abbildung 8: Verwenden Sie USA als Standardwert für den country
Parameter (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Nach Abschluss des Assistenten enthält die GridView ein BoundField für jedes Der Lieferantendatenfelder. Entfernen Sie alle außer CompanyName
, City
und Country
BoundFields, und benennen Sie die CompanyName
BoundFields-Eigenschaft HeaderText
in Supplier um. Danach sollte die deklarative Syntax GridView und ObjectDataSource wie folgt aussehen.
<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>
In diesem Tutorial ermöglichen wir dem Benutzer, die Produkte des ausgewählten Lieferanten auf derselben Seite wie die Lieferantenliste oder auf einer anderen Seite anzuzeigen. Um dies zu ermöglichen, fügen Sie der Seite zwei Schaltflächen-Websteuerelemente hinzu. Ich habe die ID
s dieser beiden Schaltflächen auf ListProducts
und SendToProducts
festgelegt, mit der Idee, dass, wenn ListProducts
geklickt wird, ein Postback erfolgt und die ausgewählten Produkte des Lieferanten auf derselben Seite aufgeführt werden, aber wenn SendToProducts
geklickt wird, wird der Benutzer zu einer anderen Seite weitergeleitet, auf der die Produkte aufgeführt sind.
Abbildung 9 zeigt die Suppliers
GridView und die beiden Button-Websteuerelemente, wenn sie über einen Browser angezeigt werden.
Abbildung 9: Bei diesen Lieferanten aus den USA sind ihre Informationen zu Name, Ort und Land aufgelistet (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Schritt 3: Hinzufügen einer Spalte mit Optionsfeldern
An diesem Punkt verfügt gridView Suppliers
über drei BoundFields, die den Firmennamen, den Ort und das Land der einzelnen Lieferanten in den USA anzeigen. Es fehlt jedoch noch eine Spalte mit Optionsfeldern. Leider enthält die GridView kein integriertes RadioButtonField, andernfalls könnten wir das einfach dem Raster hinzufügen und fertig sein. Stattdessen können wir ein TemplateField hinzufügen und dessen ItemTemplate
so konfigurieren, dass ein Optionsfeld gerendert wird, was zu einem Optionsfeld für jede GridView-Zeile führt.
Zunächst können wir davon ausgehen, dass die gewünschte Benutzeroberfläche durch Hinzufügen eines RadioButton-Websteuerelements zu ItemTemplate
einem TemplateField implementiert werden kann. Dies fügt zwar jeder Zeile des GridView-Steuerelements ein einzelnes Optionsfeld hinzu, die Optionsfelder können jedoch nicht gruppiert werden und schließen sich daher nicht aus. Das heißt, ein Endbenutzer kann mehrere Optionsfelder gleichzeitig aus der GridView auswählen.
Auch wenn die Verwendung eines TemplateField-Steuerelements von RadioButton-Websteuerelementen nicht die erforderlichen Funktionen bietet, implementieren wir diesen Ansatz, da es sich lohnt, zu untersuchen, warum die resultierenden Optionsfelder nicht gruppiert sind. Fügen Sie zunächst ein TemplateField-Element zur GridView der Lieferanten hinzu, und machen Sie es zum linkssten Feld. Klicken Sie als Nächstes im Smarttag von GridView auf den Link Vorlagen bearbeiten, und ziehen Sie ein RadioButton-Websteuerelement aus der Toolbox in die TemplateField s ItemTemplate
(siehe Abbildung 10). Legen Sie die RadioButton-Eigenschaft ID
auf und die GroupName
-Eigenschaft auf SuppliersGroup
RowSelector
fest.
Abbildung 10: Hinzufügen eines RadioButton-Websteuerelements zu dem (Klicken Sie, um dasItemTemplate
Bild in voller Größe anzuzeigen)
Nachdem Sie diese Ergänzungen über die Designer gemacht haben, sollte Ihr GridView-Markup wie folgt aussehen:
<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>
Die RadioButton-Eigenschaft GroupName
wird verwendet, um eine Reihe von Optionsfeldern zu gruppieren. Alle RadioButton-Steuerelemente mit demselben GroupName
Wert werden als gruppiert betrachtet. Es kann jeweils nur ein Optionsfeld aus einer Gruppe ausgewählt werden. Die GroupName
-Eigenschaft gibt den Wert für das Attribut des gerenderten Optionsfelds name
an. Der Browser untersucht die Optionsfeldattribute name
, um die Optionsfeldgruppierungen zu bestimmen.
Wenn sie das RadioButton-Websteuerelement hinzugefügt ItemTemplate
haben, besuchen Sie diese Seite über einen Browser, und klicken Sie auf die Optionsfelder in den Zeilen des Rasters. Beachten Sie, dass die Optionsfelder nicht gruppiert sind, sodass alle Zeilen ausgewählt werden können, wie Abbildung 11 zeigt.
Abbildung 11: Die GridView-Optionsfelder sind nicht gruppiert (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Der Grund, warum die Optionsfelder nicht gruppiert werden, liegt daran, dass sich die gerenderten name
Attribute unterscheiden, obwohl sie dieselbe GroupName
Eigenschaftseinstellung haben. Um diese Unterschiede anzuzeigen, führen Sie im Browser eine Ansicht/Quelle aus, und überprüfen Sie das Optionsfeldmarkup:
<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" />
Beachten Sie, dass sowohl die name
Attribute als id
auch nicht die exakten Werte sind, die in der Eigenschaftenfenster angegeben sind, sondern mit einer Reihe anderer ID
Werte versehen sind. Die zusätzlichen ID
Werte, die der Vorderseite des gerenderten id
und name
-Attributs hinzugefügt werden, sind die ID
s der übergeordneten Optionsfelder, die GridViewRow
s ID
, die GridView s ID
, das Content-Steuerelement s ID
und das WebFormular s ID
. Diese ID
s werden hinzugefügt, sodass jedes gerenderte Websteuerelement in GridView über eindeutige id
Werte und name
verfügt.
Jedes gerenderte Steuerelement benötigt eine andere name
, da id
der Browser jedes Steuerelement auf der Clientseite eindeutig identifiziert und wie er dem Webserver identifiziert, welche Aktion oder Änderung beim Postback aufgetreten ist. Stellen Sie sich beispielsweise vor, wir wollten einen serverseitigen Code ausführen, wenn ein aktivierter RadioButton-Zustand geändert wurde. Hierzu können Sie die RadioButton-Eigenschaft AutoPostBack
auf True
festlegen und einen Ereignishandler für das CheckChanged
Ereignis erstellen. Wenn die Gerenderten name
und id
Werte für alle Optionsfelder jedoch identisch waren, konnten wir beim Postback nicht ermitteln, auf welche bestimmte RadioButton-Taste geklickt wurde.
Das Kurze ist, dass wir keine Spalte mit Optionsfeldern in einer GridView mit dem RadioButton-Websteuerelement erstellen können. Stattdessen müssen wir eher archaische Techniken verwenden, um sicherzustellen, dass das entsprechende Markup in jede GridView-Zeile eingefügt wird.
Hinweis
Wie das RadioButton-Websteuerelement enthält das OPTIONSFELD-HTML-Steuerelement, wenn es einer Vorlage hinzugefügt wird, das eindeutige name
Attribut, sodass die Optionsfelder im Raster aufgehoben werden. Wenn Sie mit HTML-Steuerelementen nicht vertraut sind, können Sie diesen Hinweis ignorieren, da HTML-Steuerelemente nur selten verwendet werden, insbesondere in ASP.NET 2.0. Wenn Sie jedoch mehr erfahren möchten, lesen Sie K. Scott Allens Blogeintrag Websteuerelemente und HTML-Steuerelemente.
Verwenden eines Literalsteuerelements zum Einfügen von Optionsfeldmarkups
Um alle Optionsfelder innerhalb der GridView ordnungsgemäß zu gruppieren, müssen wir das Optionsfeldmarkup manuell in das ItemTemplate
einfügen. Jedes Optionsfeld benötigt das gleiche name
Attribut, sollte aber über ein eindeutiges id
Attribut verfügen (falls wir über clientseitiges Skript auf eine Optionsschaltfläche zugreifen möchten). Nachdem ein Benutzer ein Optionsfeld ausgewählt und die Seite zurückgibt, sendet der Browser den Wert des Attributs des ausgewählten Optionsfelds value
zurück. Daher benötigt jedes Optionsfeld ein eindeutiges value
Attribut. Schließlich müssen wir beim Postback sicherstellen, dass das Attribut dem checked
ausgewählten Optionsfeld hinzugefügt wird. Andernfalls kehren die Optionsfelder nach der Auswahl und den Beiträgen zurück in den Standardzustand zurück (alle deaktiviert).
Es gibt zwei Ansätze, die verwendet werden können, um Markup auf niedriger Ebene in eine Vorlage einzufügen. Eine besteht darin, eine Mischung aus Markup und Aufrufen von Formatierungsmethoden auszuführen, die in der CodeBehind-Klasse definiert sind. Diese Technik wurde zuerst im Tutorial Verwenden von TemplateFields im GridView-Steuerelement erläutert. In unserem Fall könnte es etwa wie folgt aussehen:
<input type="radio" id='<%# GetUniqueRadioButtonID(...) %>'
name='SuppliersGroup' value='<%# GetRadioButtonValue(...) %>' ... />
Hier und GetRadioButtonValue
wären Methoden, GetUniqueRadioButton
die in der CodeBehind-Klasse definiert sind, die die entsprechenden id
Werte und value
Attributwerte für die einzelnen Optionsfelder zurückgegeben haben. Dieser Ansatz funktioniert gut für das Zuweisen der id
Attribute und value
, greift jedoch zu kurz, wenn der checked
Attributwert angegeben werden muss, da die Datenbindungssyntax nur ausgeführt wird, wenn Daten zuerst an die GridView gebunden werden. Wenn für GridView der Ansichtszustand aktiviert ist, werden die Formatierungsmethoden daher nur ausgelöst, wenn die Seite zum ersten Mal geladen wird (oder wenn gridView explizit an die Datenquelle weitergeleitet wird), und daher wird die Funktion, die das checked
Attribut festlegt, beim Postback nicht aufgerufen. Es ist ein eher subtiles Problem und etwas außerhalb des Rahmens dieses Artikels, daher werde ich es hier belassen. Ich ermutige Sie jedoch, den oben genannten Ansatz zu versuchen und bis zu dem Punkt zu arbeiten, an dem Sie hängen bleiben. Eine solche Übung bringt Sie einer funktionierenden Version zwar nicht näher, trägt jedoch zu einem tieferen Verständnis des GridView-Lebenszyklus und des Lebenszyklus der Datenbindung bei.
Der andere Ansatz zum Einfügen von benutzerdefiniertem Markup auf niedriger Ebene in eine Vorlage und der Ansatz, den wir für dieses Tutorial verwenden werden, besteht darin, der Vorlage ein Literal-Steuerelement hinzuzufügen. Anschließend kann im GridView s RowCreated
- oder RowDataBound
Ereignishandler programmgesteuert auf das Literal-Steuerelement zugegriffen werden, und seine Text
Eigenschaft kann auf das auszustrahlende Markup festgelegt werden.
Entfernen Sie zunächst radioButton aus den TemplateFields, ItemTemplate
und ersetzen Sie es durch ein Literal-Steuerelement. Legen Sie das Literal-Steuerelement s ID
auf fest RadioButtonMarkup
.
Abbildung 12: Hinzufügen eines Literalsteuerelements zum (Klicken, um dasItemTemplate
Bild in voller Größe anzuzeigen)
Erstellen Sie als Nächstes einen Ereignishandler für das GridView-Ereignis RowCreated
. Das RowCreated
Ereignis wird für jede hinzugefügte Zeile einmal ausgelöst, unabhängig davon, ob die Daten an die GridView-Instanz übergeben werden oder nicht. Das bedeutet, dass das Ereignis auch bei einem Postback, wenn die Daten aus dem RowCreated
Ansichtszustand neu geladen werden, weiterhin ausgelöst wird, und dies ist der Grund, warum wir es anstelle von RowDataBound
verwenden (was nur ausgelöst wird, wenn die Daten explizit an das Datenwebsteuerelement gebunden sind).
In diesem Ereignishandler möchten wir nur fortfahren, wenn es sich um eine Datenzeile handelt. Für jede Datenzeile möchten wir programmgesteuert auf das RadioButtonMarkup
Literal-Steuerelement verweisen und dessen Text
Eigenschaft auf das auszustrahlende Markup festlegen. Wie der folgende Code zeigt, erstellt das ausgegebene Markup ein Optionsfeld, dessen name
Attribut auf SuppliersGroup
festgelegt ist, dessen id
Attribut auf RowSelectorX
festgelegt ist, wobei X der Index der GridView-Zeile ist und dessen value
Attribut auf den Index der GridView-Zeile festgelegt ist.
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
Wenn eine GridView-Zeile ausgewählt ist und ein Postback erfolgt, interessieren wir uns für den SupplierID
des ausgewählten Lieferanten. Daher könnte man denken, dass der Wert der einzelnen Optionsfelder der tatsächliche SupplierID
(und nicht der Index der GridView-Zeile) sein sollte. Dies kann zwar unter bestimmten Umständen funktionieren, aber es wäre ein Sicherheitsrisiko, blind zu akzeptieren und zu SupplierID
verarbeiten. Unser GridView listet beispielsweise nur die Anbieter in den USA auf. Wenn die SupplierID
jedoch direkt aus dem Optionsfeld übergeben wird, was soll einen schelmischen Benutzer daran hindern, den beim Postback zurückgesendeten SupplierID
Wert zu manipulieren? Wenn Sie den Zeilenindex als value
verwenden und dann das SupplierID
On-Postback aus der DataKeys
Auflistung abrufen, können Sie sicherstellen, dass der Benutzer nur einen der Werte verwendet, die SupplierID
einer der GridView-Zeilen zugeordnet sind.
Nehmen Sie sich nach dem Hinzufügen dieses Ereignishandlercodes eine Minute Zeit, um die Seite in einem Browser zu testen. Beachten Sie zunächst, dass jeweils nur ein Optionsfeld im Raster ausgewählt werden kann. Wenn Sie jedoch ein Optionsfeld auswählen und auf eine der Schaltflächen klicken, erfolgt ein Postback, und die Optionsfelder rückgängig machen in ihren Ursprünglichen Zustand (das heißt, beim Postback ist das ausgewählte Optionsfeld nicht mehr ausgewählt). Um dies zu beheben, müssen wir den RowCreated
Ereignishandler so erweitern, dass er den ausgewählten Optionsfeldindex überprüft, der vom Postback gesendet wird, und das checked="checked"
Attribut dem ausgegebenen Markup der Zeilenindexübereinstimmungen hinzufügt.
Wenn ein Postback erfolgt, sendet der Browser das name
und value
des ausgewählten Optionsfelds zurück. Der Wert kann programmgesteuert mit Request.Form("name")
abgerufen werden. Die Request.Form
-Eigenschaft stellt eine NameValueCollection
dar, die die Formularvariablen darstellt. Die Formularvariablen sind die Namen und Werte der Formularfelder auf der Webseite und werden vom Webbrowser zurückgesendet, wenn ein Postback erfolgt. Da das gerenderte name
Attribut der Optionsfelder in der GridView lautet SuppliersGroup
, sendet der Browser (zusammen mit den anderen Formularfeldern) zurück an den Webserver, wenn die Webseite zurück gesendet wird SuppliersGroup=valueOfSelectedRadioButton
. Auf diese Informationen kann dann über die Request.Form
-Eigenschaft zugegriffen werden: Request.Form("SuppliersGroup")
.
Da wir den Index für ausgewählte Optionsfelder nicht nur im Ereignishandler, sondern in den RowCreated
Click
Ereignishandlern für die Button-Websteuerelemente ermitteln müssen, fügen wir der CodeBehind-Klasse eine SuppliersSelectedIndex
Eigenschaft hinzu, die zurückgibt -1
, wenn kein Optionsfeld ausgewählt wurde und der ausgewählte Index, wenn eine der Optionsfelder ausgewählt ist.
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
Wenn diese Eigenschaft hinzugefügt wurde, wissen wir, dass das checked="checked"
Markup im RowCreated
Ereignishandler hinzugefügt wird, wenn SuppliersSelectedIndex
gleich e.Row.RowIndex
ist. Aktualisieren Sie den Ereignishandler so, dass er diese Logik enthält:
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
Mit dieser Änderung bleibt das ausgewählte Optionsfeld nach einem Postback ausgewählt. Nachdem wir nun angeben können, welches Optionsfeld ausgewählt ist, können wir das Verhalten so ändern, dass beim ersten Besuch der Seite das Optionsfeld der ersten GridView-Zeile ausgewählt wurde (anstatt standardmäßig keine Optionsfelder ausgewählt zu haben, was das aktuelle Verhalten ist). Damit das erste Optionsfeld standardmäßig ausgewählt ist, ändern Sie einfach die If SuppliersSelectedIndex = e.Row.RowIndex Then
Anweisung in die folgende: If SuppliersSelectedIndex = e.Row.RowIndex OrElse (Not Page.IsPostBack AndAlso e.Row.RowIndex = 0) Then
.
An diesem Punkt haben wir der GridView eine Spalte gruppierter Optionsfelder hinzugefügt, mit der eine einzelne GridView-Zeile ausgewählt und postbacksübergreifend gespeichert werden kann. In den nächsten Schritten zeigen wir ihnen die Produkte des ausgewählten Lieferanten an. In Schritt 4 erfahren Sie, wie Sie den Benutzer auf eine andere Seite umleiten und die ausgewählte SupplierID
senden. In Schritt 5 erfahren Sie, wie Sie die Produkte des ausgewählten Lieferanten in einer GridView auf derselben Seite anzeigen.
Hinweis
Anstatt ein TemplateField zu verwenden (der Schwerpunkt dieses langwierigen Schritts 3), könnten wir eine benutzerdefinierte DataControlField
Klasse erstellen, die die entsprechende Benutzeroberfläche und Funktionalität rendert. Die DataControlField
-Klasse ist die Basisklasse, von der die Felder BoundField, CheckBoxField, TemplateField und andere integrierte GridView- und DetailsView-Felder abgeleitet werden. Das Erstellen einer benutzerdefinierten DataControlField
Klasse würde bedeuten, dass die Spalte von Optionsfeldern nur mithilfe der deklarativen Syntax hinzugefügt werden könnte. Außerdem würde die Replikation der Funktionalität auf anderen Webseiten und anderen Webanwendungen erheblich vereinfacht.
Wenn Sie jemals benutzerdefinierte, kompilierte Steuerelemente in ASP.NET erstellt haben, wissen Sie jedoch, dass dies eine menge Beinarbeit erfordert und eine Vielzahl von Feinheiten und Edge-Fällen mit sich bringt, die sorgfältig behandelt werden müssen. Daher verzichten wir vorerst auf die Implementierung einer Spalte mit Optionsfeldern als benutzerdefinierte DataControlField
Klasse und bleiben bei der Option TemplateField. Vielleicht haben wir die Möglichkeit, das Erstellen, Verwenden und Bereitstellen benutzerdefinierter DataControlField
Klassen in einem zukünftigen Tutorial zu erkunden!
Schritt 4: Anzeigen der produkte des ausgewählten Lieferanten auf einer separaten Seite
Nachdem der Benutzer eine GridView-Zeile ausgewählt hat, müssen wir die Produkte des ausgewählten Lieferanten anzeigen. Unter bestimmten Umständen möchten wir diese Produkte möglicherweise auf einer separaten Seite anzeigen, in anderen fällen wir es vor, dies auf derselben Seite zu tun. Sehen wir uns zunächst an, wie die Produkte auf einer separaten Seite angezeigt werden. In Schritt 5 sehen wir uns das Hinzufügen einer GridView zu an, um RadioButtonField.aspx
die Produkte des ausgewählten Lieferanten anzuzeigen.
Derzeit gibt es zwei Button-Websteuerelemente auf der Seite ListProducts
und SendToProducts
. Wenn auf die SendToProducts
Schaltfläche geklickt wird, möchten wir den Benutzer an ~/Filtering/ProductsForSupplierDetails.aspx
senden. Diese Seite wurde im Tutorial Master-/Detailfilterung über zwei Seiten erstellt und zeigt die Produkte für den Lieferanten an, dessen SupplierID
Abfragezeichenfolgenfeld mit dem Namen SupplierID
übergeben wird.
Um diese Funktionalität bereitzustellen, erstellen Sie einen Ereignishandler für das SendToProducts
Button-Ereignis Click
. In Schritt 3 haben wir die SuppliersSelectedIndex
-Eigenschaft hinzugefügt, die den Index der Zeile zurückgibt, deren Optionsfeld ausgewählt ist. Das entsprechende SupplierID
kann aus der GridView-Sammlung DataKeys
abgerufen werden, und der Benutzer kann dann mithilfe Response.Redirect("url")
von an gesendet ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID
werden.
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
Dieser Code funktioniert wunderbar, solange eine der Optionsfelder in der GridView ausgewählt ist. Wenn für GridView zunächst keine Optionsfelder ausgewählt sind und der Benutzer auf die SendToProducts
Schaltfläche klickt, wird -1
eine Ausnahme ausgelöst, SuppliersSelectedIndex
da -1
sich der Indexbereich der DataKeys
Auflistung nicht befindet. Dies ist jedoch kein Problem, wenn Sie sich entschieden haben, den RowCreated
Ereignishandler wie in Schritt 3 erläutert zu aktualisieren, um das erste Optionsfeld in der GridView anfänglich ausgewählt zu haben.
Fügen Sie der Seite über der GridView ein Label-Websteuerelement hinzu, um einen SuppliersSelectedIndex
Wert von -1
aufzunehmen. Legen Sie ihre ID
Eigenschaft auf ChooseSupplierMsg
, ihre CssClass
Eigenschaft auf Warning
, ihre EnableViewState
und Visible
die Eigenschaften auf False
fest, und ihre Text
Eigenschaft auf Bitte wählen Sie einen Lieferanten aus dem Raster aus. Die CSS-Klasse Warning
zeigt Text in einer roten, kursiven, fetten, großen Schriftart an und ist in Styles.css
definiert. Durch Festlegen der EnableViewState
Eigenschaften und Visible
auf False
wird die Bezeichnung nicht gerendert, mit Ausnahme der Postbacks, bei denen die Eigenschaft des Steuerelements Visible
programmgesteuert auf True
festgelegt ist.
Abbildung 13: Hinzufügen eines Beschriftungs-Websteuerelements über der GridView (Klicken Sie hier, um ein vollständiges Bild anzuzeigen)
Erweitern Sie als Nächstes den Click
Ereignishandler, um die ChooseSupplierMsg
Bezeichnung anzuzeigen, wenn SuppliersSelectedIndex
kleiner als null ist, und leiten Sie den Benutzer an einen anderen Wert weiter ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID
.
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
Besuchen Sie die Seite in einem Browser, und klicken Sie auf die SendToProducts
Schaltfläche, bevor Sie einen Lieferanten aus der GridView auswählen. Wie Abbildung 14 zeigt, wird die ChooseSupplierMsg
Bezeichnung angezeigt. Wählen Sie als Nächstes einen Lieferanten aus, und klicken Sie auf die SendToProducts
Schaltfläche. Dadurch gelangen Sie zu einer Seite, auf der die vom ausgewählten Lieferanten gelieferten Produkte aufgeführt sind. Abbildung 15 zeigt die ProductsForSupplierDetails.aspx
Seite, auf der der Lieferant von Bigfoot Breweries ausgewählt wurde.
Abbildung 14: Die ChooseSupplierMsg
Bezeichnung wird angezeigt, wenn Kein Lieferant ausgewählt ist (Klicken Sie, um das bild in voller Größe anzuzeigen)
Abbildung 15: Die produkte des ausgewählten Lieferanten werden in ProductsForSupplierDetails.aspx
angezeigt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Schritt 5: Anzeigen der ausgewählten Lieferantenprodukte auf derselben Seite
In Schritt 4 haben wir erfahren, wie der Benutzer zu einer anderen Webseite gesendet wird, um die Produkte des ausgewählten Lieferanten anzuzeigen. Alternativ können die produkte des ausgewählten Lieferanten auf derselben Seite angezeigt werden. Um dies zu veranschaulichen, fügen wir eine weitere GridView hinzu, um RadioButtonField.aspx
die produkte des ausgewählten Lieferanten anzuzeigen.
Da diese GridView von Produkten nur angezeigt werden soll, nachdem ein Lieferant ausgewählt wurde, fügen Sie ein Panel-Websteuerelement unter gridView Suppliers
hinzu, und legen Sie dessen ID
auf ProductsBySupplierPanel
und seine Visible
-Eigenschaft auf False
fest. Fügen Sie im Panel den Text Produkte für den ausgewählten Lieferanten hinzu, gefolgt von einer GridView mit dem Namen ProductsBySupplier
. Wählen Sie im Smarttag von GridView aus, um es an eine neue ObjectDataSource mit dem Namen ProductsBySupplierDataSource
zu binden.
Abbildung 16: Binden von ProductsBySupplier
GridView an eine neue ObjectDataSource (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Konfigurieren Sie als Nächstes objectDataSource für die Verwendung der ProductsBLL
-Klasse. Da wir nur die vom ausgewählten Lieferanten bereitgestellten Produkte abrufen möchten, geben Sie an, dass objectDataSource die GetProductsBySupplierID(supplierID)
-Methode aufrufen soll, um die Daten abzurufen. Wählen Sie in den Dropdownlisten auf den Registerkarten UPDATE, INSERT und DELETE (Keine) aus.
Abbildung 17: Konfigurieren der ObjectDataSource für die Verwendung der GetProductsBySupplierID(supplierID)
-Methode (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Abbildung 18: Festlegen der Drop-Down Listen auf (Keine) in den Registerkarten UPDATE, INSERT und DELETE (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Klicken Sie nach dem Konfigurieren der Registerkarten SELECT, UPDATE, INSERT und DELETE auf Weiter. Da die GetProductsBySupplierID(supplierID)
-Methode einen Eingabeparameter erwartet, werden wir vom Assistenten zum Erstellen einer Datenquelle aufgefordert, die Quelle für den Wert des Parameters s anzugeben.
Wir haben hier eine Reihe von Optionen, um die Quelle des Parameterwerts anzugeben. Wir könnten das Standardobjekt Parameter verwenden und den Wert der SuppliersSelectedIndex
Eigenschaft programmgesteuert der Parameter s-Eigenschaft DefaultValue
im ObjectDataSource-Ereignishandler Selecting
zuweisen. Eine Aktualisierung zum programmgesteuerten Zuweisen von Werten zu den Parametern von ObjectDataSource finden Sie im Tutorial Programmgesteuertes Festlegen der Parameter von ObjectDataSource .
Alternativ können wir einen ControlParameter verwenden und auf die Suppliers
GridView-Eigenschaft SelectedValue
verweisen (siehe Abbildung 19). Die GridView-Eigenschaft SelectedValue
gibt den Wert zurück, der DataKey
der SelectedIndex
-Eigenschaft entspricht. Damit diese Option funktioniert, müssen wir die Eigenschaft GridView s SelectedIndex
programmgesteuert auf die ausgewählte Zeile festlegen, wenn auf die ListProducts
Schaltfläche geklickt wird. Als zusätzlichen Vorteil erhält SelectedRowStyle
der ausgewählte Datensatz durch Festlegen von SelectedIndex
den im DataWebControls
Design definierten (gelben Hintergrund).
Abbildung 19: Verwenden eines ControlParameter zum Angeben des SelectedValue-Werts von GridView als Parameterquelle (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Nach Abschluss des Assistenten fügt Visual Studio automatisch Felder für die Datenfelder des Produkts hinzu. Entfernen Sie alle außer ProductName
, CategoryName
und UnitPrice
BoundFields, und ändern Sie die HeaderText
Eigenschaften in Product, Category und Price. Konfigurieren Sie das UnitPrice
BoundField so, dass sein Wert als Währung formatiert ist. Nachdem Sie diese Änderungen vorgenommen haben, sollte das deklarative Markup Panel, GridView und ObjectDataSource wie folgt aussehen:
<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>
Um diese Übung abzuschließen, müssen wir die Eigenschaft GridView s SelectedIndex
auf und SelectedSuppliersIndex
die ProductsBySupplierPanel
Eigenschaft Panel s Visible
auf True
festlegen, wenn auf die ListProducts
Schaltfläche geklickt wird. Um dies zu erreichen, erstellen Sie einen Ereignishandler für das ListProducts
Button-Websteuerelement-Ereignis, Click
und fügen Sie den folgenden Code hinzu:
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
Wenn kein Lieferant aus gridView ausgewählt wurde, wird die ChooseSupplierMsg
Bezeichnung und der ProductsBySupplierPanel
Bereich ausgeblendet angezeigt. Andernfalls wird angezeigt, wenn ein Lieferant ausgewählt wurde, ProductsBySupplierPanel
und die GridView-Eigenschaft SelectedIndex
wird aktualisiert.
Abbildung 20 zeigt die Ergebnisse, nachdem der Anbieter bigfoot Breweries ausgewählt wurde und auf die Schaltfläche Produkte auf Seite anzeigen geklickt wurde.
Abbildung 20: Die von Bigfoot Breweries bereitgestellten Produkte sind auf derselben Seite aufgeführt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Zusammenfassung
Wie im Tutorial Master/Detail Using a Selectable Master GridView with a Details DetailView beschrieben, können Datensätze aus einer GridView mithilfe eines CommandField ausgewählt werden, dessen ShowSelectButton
Eigenschaft auf True
festgelegt ist. Das CommandField zeigt seine Schaltflächen jedoch entweder als normale Drucktasten, Links oder Bilder an. Eine alternative Benutzeroberfläche für die Zeilenauswahl ist die Bereitstellung eines Optionsfelds oder Kontrollkästchens in jeder GridView-Zeile. In diesem Tutorial haben wir uns mit dem Hinzufügen einer Spalte mit Optionsfeldern befasst.
Leider ist das Hinzufügen einer Spalte von Optionsfeldern nicht so einfach oder einfach, wie man es erwarten könnte. Es gibt kein integriertes RadioButtonField, das beim Klicken einer Schaltfläche hinzugefügt werden kann, und die Verwendung des RadioButton-Websteuerelements in einem TemplateField führt zu eigenen Problemen. Um eine solche Schnittstelle bereitzustellen, müssen wir entweder eine benutzerdefinierte DataControlField
Klasse erstellen oder den entsprechenden HTML-Code während des RowCreated
Ereignisses in ein TemplateField einfügen.
Nachdem wir uns mit dem Hinzufügen einer Spalte mit Optionsfeldern beschäftigt haben, richten wir unsere Aufmerksamkeit auf das Hinzufügen einer Spalte mit Kontrollkästchen. Mit einer Spalte mit Kontrollkästchen kann ein Benutzer eine oder mehrere GridView-Zeilen auswählen und dann einen Vorgang für alle ausgewählten Zeilen ausführen (z. B. auswählen einer Reihe von E-Mails von einem webbasierten E-Mail-Client und anschließendes Löschen aller ausgewählten E-Mails). Im nächsten Tutorial erfahren Sie, wie Sie eine solche Spalte hinzufügen.
Viel Spaß beim Programmieren!
Zum Autor
Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.
Besonderer Dank an
Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Leitender Prüfer für dieses Tutorial war David Suru. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.