Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
von Scott Mitchell
In diesem Lernprogramm wird erläutert, wie Sie einem GridView-Steuerelement eine Spalte mit Radiobuttons hinzufügen, um eine intuitivere Methode für den Benutzer zum Auswählen einer einzelnen Zeile des GridView bereitzustellen.
Einleitung
Das GridView-Steuerelement bietet viele integrierte Funktionen. Sie enthält eine Reihe verschiedener Felder zum Anzeigen von Text, Bildern, Links 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 gibt es häufig Situationen, in denen zusätzliche, nicht unterstützte Features hinzugefügt werden müssen. In diesem Lernprogramm und den nächsten beiden Werden wir untersuchen, wie Sie die GridView-Funktionalität verbessern, um zusätzliche Features einzuschließen.
Dieses Lernprogramm und das nächste fokussieren auf die Verbesserung des Zeilenauswahlprozesses. Wie im Master/Detail unter Nutzung einer auswählbaren Master-GridView mit einer Detail-Detailansicht untersucht, können wir der GridView ein CommandField hinzufügen, das eine Schaltfläche zum Auswählen enthält. Beim Klicken wird ein Postback ausgeführt, und die GridView-Eigenschaft SelectedIndex
wird auf den Index der Zeile aktualisiert, auf deren Schaltfläche "Auswählen" geklickt wurde. Im Master/Detail-Tutorial mit einer auswählbaren Master-GridView und einer Detail-Ansicht haben wir gesehen, wie wir mithilfe dieses Features Details für die ausgewählte GridView-Zeile anzeigen können.
Obwohl 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 andere 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-Einträge auswählen kann, wird das Optionsfeld wahrscheinlich der Schaltfläche "Auswählen" vorgezogen. In Situationen, in denen der Benutzer möglicherweise mehrere Datensätze auswählen kann, z. B. in einer webbasierten E-Mail-Anwendung, in der ein Benutzer mehrere Nachrichten zum Löschen auswählen möchte, bietet das Kontrollkästchen Funktionalitäten, die bei der Schaltfläche "Auswählen" oder den Optionsfeldbenutzeroberflächen nicht verfügbar sind.
In diesem Lernprogramm wird erläutert, wie Sie der GridView eine Spalte mit Optionsfeldern hinzufügen. Das folgende Tutorial erkundet die Verwendung von Kontrollkästchen.
Schritt 1: Erstellen der verbesserten GridView-Webseiten
Bevor wir mit der Verbesserung der GridView beginnen, um eine Spalte mit Optionsfeldern einzuschließen, lassen Sie uns zunächst einen Moment Zeit nehmen, um die ASP.NET-Seiten in unserem Website-Projekt 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
Gestaltungsvorlage zugeordnet wird:
Default.aspx
RadioButtonField.aspx
CheckBoxField.aspx
InsertThroughFooter.aspx
Abbildung 1: Hinzufügen der ASP.NET Seiten für die SqlDataSource-Related Lernprogramme
Wie in den anderen Ordnern Default.aspx
werden im EnhancedGridView
Ordner die Tutorials im zugehörigen Abschnitt aufgelistet. Erinnern Sie sich daran, dass das SectionLevelTutorialListing.ascx
Benutzersteuerelement diese Funktionalität bereitstellt. Fügen Sie dieses Benutzersteuerelement zu Default.aspx
hinzu, 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, um das Bild in voller Größe anzuzeigen)
Fügen Sie diese vier Seiten schließlich 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 in einem Browser zu betrachten. Das Menü auf der linken Seite enthält jetzt Elemente für die Bearbeitung, das Einfügen und Löschen von Lernprogrammen.
Abbildung 3: Die Websiteübersicht enthält jetzt Einträge für die Verbesserung der GridView-Lernprogramme.
Schritt 2: Anzeigen der Lieferanten in einer GridView
In diesem Tutorial erstellen wir ein GridView-Steuerelement, das die Lieferanten aus den USA auflistet, wobei jede Zeile des GridView ein Optionsfeld enthält. Nachdem der Benutzer einen Lieferanten über das Optionsfeld ausgewählt hat, kann er die Produkte des Lieferanten anzeigen, indem er auf die Schaltfläche klickt. Obwohl diese Aufgabe trivial klingen mag, gibt es eine Reihe von Subtilitäten, die es besonders schwierig machen. Bevor wir uns mit diesen Subtilitäten befassen, lasst uns zunächst eine GridView der Lieferantenansicht erstellen.
Öffnen Sie zunächst die RadioButtonField.aspx
Seite im EnhancedGridView
Ordner, indem Sie eine GridView aus der Toolbox auf den Designer ziehen. Legen Sie "GridView s ID
" auf Suppliers
und wählen Sie aus dem Smarttag eine neue Datenquelle aus. Erstellen Sie insbesondere eine ObjectDataSource namens SuppliersDataSource
, die ihre Daten aus dem SuppliersBLL
Objekt abruft.
Abbildung 4: Erstellen einer neuen ObjectDataSource 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, um das Bild in voller Größe anzuzeigen)
Wählen Sie auf der Registerkarte "AKTUALISIEREN" die Option (Keine) aus, und klicken Sie auf "Weiter".
Abbildung 7: Konfigurieren der ObjectDataSource für die Verwendung der Klasse (SuppliersBLL
Bilds mit voller Größe klicken)
Da die GetSuppliersByCountry(country)
Methode einen Parameter akzeptiert, fordert der Assistent "Datenquelle konfigurieren" uns zur Quelle dieses Parameters auf. Wenn Sie einen hartcodierten Wert ( USA, in diesem Beispiel) angeben möchten, lassen Sie die Dropdownliste "Parameterquelle" auf "None" festgelegt, und geben Sie den Standardwert in das Textfeld ein. Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen.
Abbildung 8: Verwenden von USA als Standardwert für den country
Parameter (Zum Anzeigen des Bilds mit voller Größe klicken)
Nach Abschluss des Assistenten enthält gridView ein BoundField für jedes der Lieferantendatenfelder. Entfernen Sie alle außer die CompanyName
, City
und Country
BoundFields, und benennen Sie die CompanyName
BoundFields-Eigenschaft HeaderText
in Supplier um. Danach sollte die deklarative Syntax "GridView" und "ObjectDataSource" ähnlich 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 Lernprogramm erlauben wir es dem Benutzer, die Produkte des ausgewählten Lieferanten auf derselben Seite wie die Lieferantenliste oder auf einer anderen Seite anzuzeigen. Fügen Sie dazu der Seite zwei Schaltflächenwebsteuerelemente hinzu. Ich habe die ID
-Einstellungen dieser beiden Schaltflächen auf ListProducts
und SendToProducts
gesetzt, mit der Idee, dass ein Postback erfolgt und die Produkte des ausgewählten Lieferanten auf derselben Seite aufgeführt werden, wenn auf ListProducts
geklickt wird. Und wenn auf SendToProducts
geklickt wird, wird der Benutzer auf eine andere Seite weitergeleitet, auf der die Produkte aufgelistet sind.
Abbildung 9 zeigt die Suppliers
GridView- und die beiden Schaltflächenwebsteuerelemente, wenn sie über einen Browser angezeigt werden.
Abbildung 9: Diese Lieferanten aus den USA haben ihren Namen, Ihre Orts- und Länderinformationen aufgelistet (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Schritt 3: Hinzufügen einer Spalte an Optionsfeldern
An diesem Punkt verfügt gridView Suppliers
über drei BoundFields, die den Firmennamen, die Stadt und das Land jedes Lieferanten in den USA anzeigen. Es fehlt jedoch noch an einer Spalte von Optionsfeldern. Leider enthält gridView kein integriertes RadioButtonField, andernfalls könnten wir das einfach zum Raster hinzufügen und fertig sein. Stattdessen können wir ein TemplateField hinzufügen und so ItemTemplate
konfigurieren, dass ein Optionsfeld gerendert wird, was zu einem Optionsfeld für jede GridView-Zeile führt.
Zunächst wird davon ausgegangen, dass die gewünschte Benutzeroberfläche implementiert werden kann, indem ein RadioButton-Websteuerelement zu ItemTemplate
einem TemplateField hinzugefügt wird. Obwohl dadurch jeder Zeile der GridView ein einzelnes Optionsfeld hinzugefügt wird, sind die Optionsfelder nicht gruppierbar und schließen sich daher nicht gegenseitig aus. Das heißt, ein Endbenutzer kann gleichzeitig mehrere Radio Buttons aus der GridView auswählen.
Obwohl ein TemplateField von RadioButton-Websteuerelementen die benötigte Funktionalität nicht bietet, sollten wir diesen Ansatz implementieren, weil es sich lohnt zu analysieren, warum die erzeugten Optionsfelder nicht gruppiert sind. Fügen Sie zunächst ein TemplateField zur Lieferanten-GridView hinzu, sodass es das linkeste Feld wird. Klicken Sie als Nächstes im Smarttag von GridView auf den Link "Vorlagen bearbeiten", und ziehen Sie ein RadioButton-Websteuerelement aus der Toolbox in das TemplateField s ItemTemplate
(siehe Abbildung 10). Legen Sie die RadioButton s-Eigenschaft ID
auf RowSelector
und die GroupName
Eigenschaft auf SuppliersGroup
.
Abbildung 10: Hinzufügen eines RadioButton-Websteuerelements zum ItemTemplate
(Klicken, um das Bild in voller Größe anzuzeigen)
Nachdem Sie diese Ergänzungen über den Designer vorgenommen haben, sollte Ihr GridView-Markup ähnlich 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 name
-Attribut des gerenderten Optionsfelds an. Der Browser untersucht die Attribute der Optionsfelder name
, um die Gruppierungen der Optionsfelder zu bestimmen.
Nachdem das RadioButton-Websteuerelement zu ItemTemplate
hinzugefügt wurde, besuchen Sie diese Seite über einen Browser und klicken Sie auf die Optionsfelder in den Zeilen des Rasters. Beachten Sie, dass die Auswahlknöpfe nicht gruppiert sind, wodurch es möglich ist, alle Zeilen auszuwählen, wie in Abbildung 11 gezeigt.
Abbildung 11: Die Optionsfelder "GridView" sind nicht gruppiert (Zum Anzeigen des Bilds mit voller Größe klicken)
Der Grund, warum die Optionsfelder nicht gruppiert werden, besteht darin, dass ihre gerenderten name
Attribute unterschiedlich sind, obwohl sie die gleiche GroupName
Eigenschaftseinstellung haben. Um diese Unterschiede anzuzeigen, öffnen Sie die Quellansicht im Browser und überprüfen Sie das Radio-Button-Markup:
<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 Attribute name
als auch id
nicht die genauen Werte sind, die im Eigenschaftenfenster angegeben sind, sondern mit einer Reihe anderer ID
Werte vorangestellt werden. Die zusätzlichen ID
Werte, die am Anfang der gerenderten id
und name
Attribute hinzugefügt werden, sind die ID
der übergeordneten Steuerelemente der Optionsfelder, die GridViewRow
ID
n, die GridView-Steuerelemente ID
, die Inhaltssteuerelemente ID
und die Webformulare ID
. Diese ID
-Werte werden hinzugefügt, damit jedes gerenderte Websteuerelement in der GridView über einzigartige id
- und name
-Werte verfügt.
Jedes gerenderte Steuerelement benötigt einen anderen name
und id
, da der Browser jedes Steuerelement auf der Clientseite eindeutig identifiziert und dem Webserver mitteilt, welche Aktion oder Änderung beim Postback stattgefunden hat. Stellen Sie sich beispielsweise vor, dass wir serverseitigen Code ausführen wollten, wenn ein aktivierter RadioButton-Zustand geändert wurde. Dazu können wir die Eigenschaft des RadioButtons auf AutoPostBack
festlegen und einen Ereignishandler für das True
-Ereignis erstellen. Wenn jedoch die gerenderten name
und id
Werte für alle Optionsfelder identisch waren, konnten wir bei einem Postback nicht ermitteln, welcher spezifische RadioButton angeklickt wurde.
Zusammengefasst lässt sich sagen, dass wir keine Spalte mit Optionsfeldern in einem 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, wodurch die Optionsfelder im Raster nicht gruppiert werden. Wenn Sie mit HTML-Steuerelementen nicht vertraut sind, können Sie diese Notiz ignorieren, da HTML-Steuerelemente selten verwendet werden, insbesondere in ASP.NET 2.0. Aber wenn Sie mehr erfahren möchten, lesen Sie K. Scott Allens Blogeintrag WebSteuerelemente und HTML-Steuerelemente.
Verwenden eines Literal-Steuerelements zum Einfügen des Radiobutton-Markups
Um alle Optionsfelder innerhalb der GridView ordnungsgemäß zu gruppieren, müssen wir das Optionsfeld-Markup manuell in das ItemTemplate
einfügen. Jedes Optionsfeld benötigt dasselbe name
-Attribut, sollte jedoch ein eindeutiges id
-Attribut haben, falls wir über ein clientseitiges Skript auf ein Optionsfeld zugreifen möchten. Nachdem ein Benutzer ein Optionsfeld auswählt und die Seite zurückgibt, sendet der Browser den Wert des ausgewählten Optionsfeld-Attributs value
zurück. Daher benötigt jedes Optionsfeld ein eindeutiges value
Attribut. Schließlich müssen wir bei einem Postback sicherstellen, dass das checked
Attribut dem ausgewählten Optionsfeld hinzugefügt wird. Andernfalls, nachdem der Benutzer eine Auswahl getroffen hat und zurücksendet, werden die Optionsfelder wieder in ihren Standardzustand (alle nicht ausgewählt) zurückversetzt.
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 zu erstellen, die in der CodeBehind-Klasse definiert sind. Diese Technik wurde zuerst im Lernprogramm "Verwendung 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 würden GetUniqueRadioButton
und GetRadioButtonValue
Methoden in der CodeBehind-Klasse definiert, die die entsprechenden id
und value
Attributwerte für jedes Optionsfeld zurückgeben. Dieser Ansatz eignet sich gut für das Zuweisen der id
- und value
-Attribute, reicht jedoch nicht aus, wenn der Wert des checked
-Attributs angegeben werden muss, da die Datenbindungssyntax nur ausgeführt wird, wenn Daten zuerst an die GridView gebunden sind. Wenn die GridView den Ansichtszustand aktiviert hat, werden die Formatierungsmethoden nur ausgelöst, wenn die Seite zum ersten Mal geladen wird (oder wenn die GridView explizit an die Datenquelle zurückgeht), und daher wird die Funktion, die das checked
Attribut festlegt, nicht für postback aufgerufen. Es ist ein ziemlich subtiles Problem und ein bisschen über den Umfang dieses Artikels hinaus, also werde ich es hier belassen. Ich möchte Sie jedoch ermutigen, den oben genannten Ansatz auszuprobieren und ihn durchzugehen, bis Sie an einem Punkt hängen bleiben. Während eine solche Übung Sie nicht näher an eine funktionierende Version bringt, wird dies dazu beitragen, ein tieferes Verständnis des GridView- und des Datenbindungslebenszyklus zu fördern.
Der andere Ansatz zum Einfügen von benutzerdefiniertem Markup auf niedriger Ebene in eine Vorlage und der Ansatz, den wir für dieses Lernprogramm verwenden werden, besteht darin, der Vorlage ein Literal-Steuerelement hinzuzufügen. Anschließend kann im GridView im 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 das RadioButton-Steuerelement aus dem TemplateField ItemTemplate
und ersetzen Sie es durch ein Literal-Steuerelement. Legen Sie das Literal-Steuerelement ID
auf RadioButtonMarkup
.
Abbildung 12: Fügen Sie ein Literal Control zu ItemTemplate
hinzu (Klicken, um das Bild in voller Größe anzuzeigen)
Erstellen Sie als Nächstes einen Ereignishandler für das GridView-Ereignis RowCreated
. Das RowCreated
Ereignis wird einmal für jede hinzugefügte Zeile ausgelöst, unabhängig davon, ob die Daten an die GridView zurückgebunden werden. Dies bedeutet, dass das Ereignis auch bei einem Postback, wenn die Daten aus dem View-State neu geladen werden, RowCreated
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 Markup festlegen, das ausgegeben werden soll. 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 auftritt, interessieren wir uns für den SupplierID
des ausgewählten Lieferanten. Daher könnte man denken, dass der Wert jedes Optionsfelds der tatsächliche SupplierID
Wert sein sollte (anstelle des Indexes der GridView-Zeile). Dies kann zwar unter bestimmten Umständen funktionieren, aber es wäre ein Sicherheitsrisiko, blind eine SupplierID
anzunehmen und zu verarbeiten. Unsere GridView listet beispielsweise nur die Lieferanten in den USA auf. Wenn das SupplierID
jedoch direkt vom Optionsfeld übergeben wird, was soll einen schadenfreudigen Benutzer daran hindern, den SupplierID
zurückgesendeten Wert beim Postback zu manipulieren? Durch die Verwendung des Zeilenindexes als value
und das Abrufen des SupplierID
beim Postback aus der DataKeys
Sammlung können wir sicherstellen, dass der Benutzer nur einen der SupplierID
Werte verwendet, die mit einer der GridView-Zeilen verbunden sind.
Nachdem Sie diesen Ereignishandlercode hinzugefügt haben, nehmen Sie sich 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, tritt ein Postback auf, und die Optionsfelder werden in ihren Anfangszustand zurückgesetzt (d. h. bei einem 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 aus dem Postback gesendeten ausgewählten Optionsfeldindex überprüft und das checked="checked"
Attribut dem ausgegebenen Markup hinzufügt, wenn der Zeilenindex übereinstimmt.
Wenn ein Postback auftritt, sendet der Browser die name
und value
des ausgewählten Optionsfelds zurück. Der Wert kann programmatisch mithilfe von Request.Form("name")
abgerufen werden. Die Request.Form
Eigenschaft repräsentiert die NameValueCollection
Formularvariablen. Die Formularvariablen sind die Namen und Werte der Formularfelder auf der Webseite und werden immer dann vom Webbrowser zurückgesendet, wenn ein Postback erfolgt. Da das gerenderte name
-Attribut der Optionsfelder in der GridView SuppliersGroup
ist, sendet der Browser bei einem erneuten Absenden der Webseite SuppliersGroup=valueOfSelectedRadioButton
zurück an den Webserver (zusammen mit den anderen Formularfeldern). Auf diese Informationen kann dann über die Request.Form
Eigenschaft zugegriffen werden: Request.Form("SuppliersGroup")
.
Da wir den ausgewählten Optionsfeldindex nicht nur im RowCreated
Ereignishandler bestimmen müssen, sondern in den Click
Ereignishandlern für die Schaltflächenwebsteuerelemente, fügen wir der CodeBehind-Klasse eine SuppliersSelectedIndex
Eigenschaft hinzu, die zurückgibt -1
, wenn kein Optionsfeld ausgewählt wurde, und den ausgewählten Index, wenn eines 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 wir das checked="checked"
-Markup im RowCreated
-Ereignishandler hinzufügen, 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
Bei dieser Änderung bleibt das ausgewählte Optionsfeld nach einem Postback ausgewählt. Nachdem wir nun die Möglichkeit haben, anzugeben, 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). Um das erste Optionsfeld standardmäßig auszuwählen, ändern Sie einfach die If SuppliersSelectedIndex = e.Row.RowIndex Then
Anweisung in Folgendes: If SuppliersSelectedIndex = e.Row.RowIndex OrElse (Not Page.IsPostBack AndAlso e.Row.RowIndex = 0) Then
An diesem Punkt haben wir der GridView eine Spalte mit gruppierten Optionsfeldern hinzugefügt, mit der eine einzelne GridView-Zeile ausgewählt und über Postbacks hinweg gespeichert werden kann. Unsere nächsten Schritte sind das Anzeigen der vom ausgewählten Lieferanten bereitgestellten Produkte. In Schritt 4 erfahren wir, wie der Benutzer auf eine andere Seite umgeleitet wird, wobei das ausgewählte SupplierID
mitgeschickt wird. In Schritt 5 wird gezeigt, wie die produkte des ausgewählten Lieferanten in einer GridView auf derselben Seite angezeigt werden.
Hinweis
Anstatt ein TemplateField zu verwenden (der Fokus 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 sind. Das Erstellen einer benutzerdefinierten DataControlField
Klasse würde bedeuten, dass die Spalte mit Optionsfeldern nur mit deklarativer Syntax hinzugefügt werden könnte, und würde auch die Replikation der Funktionalität auf anderen Webseiten und anderen Webanwendungen erheblich vereinfachen.
Wenn Sie jemals benutzerdefinierte, kompilierte Steuerelemente in ASP.NET erstellt haben, wissen Sie jedoch, dass dies erheblichen Aufwand erfordert und eine Vielzahl von Feinheiten und Sonderfällen mit sich bringt, die sorgfältig behandelt werden müssen. Daher werden wir vorerst auf die Implementierung einer Spalte von Optionsfeldern als benutzerdefinierte DataControlField
Klasse verzichten und die TemplateField-Option beibehalten. Vielleicht haben wir die Möglichkeit, das Erstellen, Verwenden und Bereitstellen von benutzerdefinierten Klassen in einem zukünftigen DataControlField
Lernprogramm 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 ausgewählten Lieferantenprodukte anzeigen. Unter bestimmten Umständen möchten wir diese Produkte möglicherweise auf einer separaten Seite anzeigen, bei anderen möchten wir es lieber auf derselben Seite tun. Lassen Sie uns zunächst untersuchen, wie die Produkte auf einer separaten Seite angezeigt werden können; In Schritt 5 sehen wir uns an, wie ein GridView-Steuerelement zu RadioButtonField.aspx
hinzugefügt werden kann, um die Produkte des ausgewählten Lieferanten anzuzeigen.
Derzeit gibt es zwei Schaltflächen-Websteuerelemente auf der Seite ListProducts
und SendToProducts
. Beim Klicken auf die SendToProducts
-Schaltfläche soll der Benutzer zu ~/Filtering/ProductsForSupplierDetails.aspx
geleitet werden. Diese Seite wurde im Tutorial "Master/Detailfilterung über zwei Seiten hinweg" erstellt und zeigt die Produkte für den Lieferanten an, dessen SupplierID
durch das 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. Die entsprechenden SupplierID
können aus der DataKeys
-Sammlung von GridView abgerufen werden, und der Benutzer kann dann mithilfe von ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID
an Response.Redirect("url")
gesendet 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 einwandfrei, solange eines der Optionsfelder aus der GridView ausgewählt ist. Wenn die GridView anfänglich keine Optionsfelder ausgewählt hat und der Benutzer auf die SendToProducts
Schaltfläche klickt, wird SuppliersSelectedIndex
-1
, was dazu führt, dass eine Ausnahme ausgelöst wird, da -1
außerhalb des Indexbereichs der DataKeys
Auflistung liegt. Dies ist jedoch kein Problem, wenn Sie sich entschieden haben, den RowCreated
Ereignishandler zu aktualisieren, wie in Schritt 3 beschrieben, damit das erste Optionsfeld in der GridView standardmäßig ausgewählt ist.
Fügen Sie oberhalb des GridViews ein Label-Websteuerelement hinzu, um einen SuppliersSelectedIndex
-Wert von -1
aufzunehmen. Setze seine ID
-Eigenschaft auf ChooseSupplierMsg
, seine CssClass
-Eigenschaft auf Warning
, seine EnableViewState
- und Visible
-Eigenschaften auf False
, und seine Text
-Eigenschaft, um einen Lieferanten aus dem Raster auszuwählen. Die CSS-Klasse Warning
zeigt Text in einer roten, kursiven, fett formatierten, großen Schriftart an und wird in Styles.css
definiert. Durch Festlegen der EnableViewState
- und Visible
-Eigenschaft auf False
wird das Label nicht gerendert, außer nur für jene Postbacks, bei denen die Visible
-Eigenschaft des Steuerelements programmgesteuert auf True
festgelegt ist.
Abbildung 13: Hinzufügen eines Bezeichnungswebsteuerelements oberhalb der GridView (Klicken Sie hier, um das Bild mit voller Größe anzuzeigen)
Erweitern Sie als Nächstes den Click
-Ereignishandler, um die ChooseSupplierMsg
-Bezeichnung anzuzeigen, wenn SuppliersSelectedIndex
kleiner als 0 ist, und leiten Sie den Benutzer andernfalls zu ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID
um.
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 in Abbildung 14 dargestellt, zeigt dies die ChooseSupplierMsg
Beschriftung an. 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 bereitgestellten Produkte aufgelistet sind. Abbildung 15 zeigt die ProductsForSupplierDetails.aspx
Seite, auf der der Lieferant der Bigfoot Breweries ausgewählt wurde.
Abbildung 14: Das ChooseSupplierMsg
Etikett wird angezeigt, wenn kein Lieferant ausgewählt ist (Zum Anzeigen des Bilds mit voller Größe klicken)
Abbildung 15: Die Produkte des ausgewählten Lieferanten werden angezeigt ProductsForSupplierDetails.aspx
(Zum Anzeigen des Bilds mit voller Größe klicken)
Schritt 5: Anzeigen der Produkte des ausgewählten Lieferanten auf derselben Seite
In Schritt 4 haben wir gesehen, wie der Benutzer an eine andere 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 die Produkte des ausgewählten Lieferanten bei RadioButtonField.aspx
anzuzeigen.
Da wir möchten, dass diese GridView von Produkten erst angezeigt wird, nachdem ein Lieferant ausgewählt wurde, fügen Sie ein Panel-Web-Steuerelement unterhalb der Suppliers
GridView hinzu und setzen Sie dessen ID
auf ProductsBySupplierPanel
und seine Eigenschaft Visible
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, ob sie an eine neue ObjectDataSource mit dem Namen ProductsBySupplierDataSource
gebunden werden soll.
Abbildung 16: Binden der ProductsBySupplier
GridView an eine neue ObjectDataSource (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Konfigurieren Sie als Nächstes die 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 die ObjectDataSource die Methode aufrufen soll, um die GetProductsBySupplierID(supplierID)
Daten abzurufen. Wählen Sie (Keine) aus den Dropdownlisten in den Registerkarten UPDATE, INSERT und DELETE aus.
Abbildung 17: Konfigurieren der ObjectDataSource für die Verwendung der GetProductsBySupplierID(supplierID)
Methode (Klicken, 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, 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, fordert der Assistent zum Erstellen von Datenquellen uns auf, die Quelle für den Wert des Parameters anzugeben.
Wir haben hier einige Optionen, um die Quelle des Werts des Parameters anzugeben. Wir können das Standardparameterobjekt verwenden und den Wert der SuppliersSelectedIndex
Eigenschaft programmgesteuert der Eigenschaft parameter s-Eigenschaft DefaultValue
im ObjectDataSource-Ereignishandler Selecting
zuweisen. Verweisen Sie auf das Tutorial zum Programmgesteuerten Festlegen der Parameterwerte von ObjectDataSource, um sich mit dem programmgesteuerten Zuweisen von Werten zu den Parametern von ObjectDataSource vertraut zu machen.
Alternativ können wir einen ControlParameter verwenden und auf die Suppliers
GridView-Eigenschaft SelectedValue
verweisen (siehe Abbildung 19). Die GridView s-Eigenschaft SelectedValue
gibt den Wert zurück, der DataKey
der SelectedIndex
Eigenschaft entspricht. Damit diese Option funktioniert, müssen wir die GridView-Eigenschaft SelectedIndex
programmgesteuert auf die ausgewählte Zeile festlegen, wenn auf die ListProducts
Schaltfläche geklickt wird. Als zusätzlichen Vorteil wird der ausgewählte Datensatz das Element SelectedIndex
übernehmen, das im SelectedRowStyle
-Thema (ein gelber Hintergrund) definiert ist, indem DataWebControls
festgelegt wird.
Abbildung 19: Verwenden Sie einen ControlParameter, um den SelectedValue der GridView als Parameterquelle anzugeben (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 Eigenschaften außer den ProductName
, CategoryName
und UnitPrice
BoundFields, und ändern Sie die HeaderText
Eigenschaften in "Product", "Category" und "Price". Konfigurieren Sie das UnitPrice
BoundField so, dass der Wert als Währung formatiert ist. Nachdem Sie diese Änderungen vorgenommen haben, sollte das deklarative Markup von 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 GridView-Eigenschaft SelectedIndex
auf SelectedSuppliersIndex
setzen und die Panel-Eigenschaft ProductsBySupplierPanel
auf Visible
festlegen, wenn die Schaltfläche True
geklickt wird. Erstellen Sie hierzu einen Ereignishandler für das Ereignis des ListProducts
Button-Websteuerelements 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 ein Lieferant nicht aus der GridView ausgewählt wurde, wird das ChooseSupplierMsg
Etikett angezeigt und der ProductsBySupplierPanel
Bereich ausgeblendet. Ansonsten wird, wenn ein Lieferant ausgewählt wurde, das ProductsBySupplierPanel
angezeigt und die SelectedIndex
-Eigenschaft von GridView wird aktualisiert.
Abbildung 20 zeigt die Ergebnisse, nachdem der Lieferant der Bigfoot Breweries ausgewählt wurde und auf die Schaltfläche "Produkte auf Seite anzeigen" geklickt wurde.
Abbildung 20: Die von Bigfoot Brauereien gelieferten Produkte werden auf derselben Seite aufgelistet (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Zusammenfassung
Wie im Master/Detail-Tutorial mit einem auswählbaren Master-GridView und einem Details-DetailView erläutert, können Datensätze aus einem GridView ausgewählt werden, indem ein CommandField verwendet wird, dessen ShowSelectButton
-Eigenschaft auf True
festgelegt ist. Das CommandField zeigt seine Schaltflächen jedoch entweder als normale Pushschaltflächen, Links oder Bilder an. Eine alternative Benutzeroberfläche zur Zeilenauswahl besteht darin, ein Optionsfeld oder ein Kontrollkästchen in jeder GridView-Zeile zur Verfügung zu stellen. In diesem Tutorial haben wir untersucht, wie man eine Spalte mit Optionsfeldern hinzufügt.
Leider ist das Hinzufügen einer Spalte mit Optionsfeldern nicht so problemlos oder unkompliziert wie erwartet. Es gibt kein integriertes RadioButtonField, das beim Klicken auf eine 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 untersucht haben, wie Sie eine Spalte mit Optionsfeldern hinzufügen können, wenden wir uns nun dem Hinzufügen einer Spalte mit Kontrollkästchen zu. 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 Lernprogramm erfahren Sie, wie Sie eine solche Spalte hinzufügen.
Glückliche Programmierung!
Zum Autor
Scott Mitchell, Autor von sieben ASP/ASP.NET Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft Web Technologies zusammen. Scott arbeitet als unabhängiger Berater, Trainer und Schriftsteller. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann bei mitchell@4GuysFromRolla.comerreicht werden.
Besonderer Dank an
Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitender Prüfer für dieses Lernprogramm war David Suru. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn ja, schicken Sie mir eine Nachricht an mitchell@4GuysFromRolla.com.