Share via


Hinzufügen einer GridView-Spalte mit Optionsfeldern (C#)

von Scott Mitchell

PDF herunterladen

In diesem Tutorial erfahren Sie, wie Sie einem GridView-Steuerelement eine Spalte mit Optionsfeldern hinzufügen, um dem Benutzer eine intuitivere Möglichkeit zum Auswählen einer einzelnen Zeile des GridView-Steuerelements zu bieten.

Einführung

Das GridView-Steuerelement bietet viele integrierte Funktionen. Es enthält eine Reihe verschiedener Felder 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 Vielzahl der bereitgestellten Features gibt es häufig Situationen, in denen zusätzliche, nicht unterstützte Features hinzugefügt werden müssen. In diesem Und den nächsten beiden Lernprogramm wird untersucht, wie Sie die GridView-Funktionalität erweitern, um zusätzliche Features einzuschließen.

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 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 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 Details DetailView ) wurde erläutert, wie Sie dieses Feature verwenden, um Details für die ausgewählte GridView-Zeile anzuzeigen.

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 gridView so erweitern, dass 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, wird das Optionsfeld möglicherweise 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, wo 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 optionsfeld-Benutzeroberflächen verfügbar sind.

In diesem Tutorial erfahren Sie, wie Sie der GridView-Ansicht 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. Fügen Sie zunächst einen neuen Ordner mit dem Namen hinzu EnhancedGridView. Fügen Sie als Nächstes die folgenden ASP.NET Seiten zu diesem Ordner hinzu, und stellen Sie sicher, dass Sie jede Seite der Site.master master Seite zuordnen:

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

Hinzufügen der ASP.NET-Seiten für die SqlDataSource-Related Tutorials

Abbildung 1: Hinzufügen der ASP.NET-Seiten für die SqlDataSource-Related Tutorials

Wie in den anderen Ordnern Default.aspx listet der EnhancedGridView Ordner die Tutorials in seinem Abschnitt auf. Denken Sie daran, dass das SectionLevelTutorialListing.ascx Benutzersteuerelement diese Funktionalität bereitstellt. Fügen Sie daher dieses Benutzersteuerelement zu Default.aspx hinzu, indem Sie es vom Projektmappen-Explorer in die Entwurfsansicht der Seite ziehen.

Hinzufügen des SectionLevelTutorialListing.ascx-Benutzersteuerelements zu Default.aspx

Abbildung 2: Hinzufügen des SectionLevelTutorialListing.ascx Benutzersteuerelements zu (Klicken Sie hier, umDefault.aspx 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.sitemapeinen Moment Zeit, um die Tutorials-Website über einen Browser anzuzeigen. Das Menü auf der linken Seite enthält nun Elemente zum Bearbeiten, Einfügen und Löschen von Tutorials.

Die Siteübersicht enthält jetzt Einträge für die Tutorials zur Verbesserung der GridView

Abbildung 3: Die Websiteübersicht enthält jetzt Einträge für die Tutorials zur Verbesserung der GridView

Schritt 2: Anzeigen der Lieferanten in einer GridView

In diesem Tutorial wird ein GridView-Objekt erstellt, das die Lieferanten aus den USA auflistet, wobei jede GridView-Zeile ein Optionsfeld bereitstellt. Nach 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 klingen mag, gibt es eine Reihe von Feinheiten, die sie besonders schwierig machen. Bevor wir uns mit diesen Feinheiten befassen, erhalten wir zunächst ein GridView-Element, das die Lieferanten auflistet.

Öffnen Sie zunächst die RadioButtonField.aspx Seite im EnhancedGridView Ordner, indem Sie ein GridView-Objekt aus der Toolbox auf die Designer ziehen. Legen Sie die GridViews ID auf fest Suppliers , und wählen Sie aus dem zugehörigen Smarttag aus, um eine neue Datenquelle zu erstellen. Erstellen Sie insbesondere eine ObjectDataSource mit dem Namen SuppliersDataSource , die ihre Daten aus dem SuppliersBLL -Objekt abruft.

Erstellen einer neuen ObjectDataSource mit dem Namen SuppliersDataSource

Abbildung 4: Erstellen einer neuen ObjectDataSource namens SuppliersDataSource (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Screenshot: Fenster

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.

Screenshot des Fensters

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.

Screenshot: Fenster

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 der Assistent Datenquelle konfigurieren uns zur Eingabe der Quelle dieses Parameters auf. Um einen hartcodierten Wert ( in diesem Beispiel USA) anzugeben, 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.

Verwenden von USA als Standardwert für den Country-Parameter

Abbildung 8: Verwenden von 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 GridView ein BoundField für jedes der Lieferantendatenfelder. Entfernen Sie alle außer CompanyName, Cityund Country BoundFields, und benennen Sie die CompanyName BoundFields-Eigenschaft HeaderText in Supplier um. Danach sollte die deklarative Syntax GridView und ObjectDataSource in etwa 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öglicht es dem Benutzer, die produkte des ausgewählten Lieferanten auf derselben Seite wie die Lieferantenliste oder auf einer anderen Seite anzuzeigen. Um dies zu berücksichtigen, fügen Sie der Seite zwei Button-Websteuerelemente hinzu. Ich habe die ID s dieser beiden Schaltflächen auf ListProducts und SendToProductsfestgelegt, 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 geführt, auf der die Produkte aufgeführt sind.

Abbildung 9 zeigt das Suppliers GridView-Steuerelement und die beiden Button Web-Steuerelemente, wenn sie über einen Browser angezeigt werden.

Diese Lieferanten aus den USA haben ihren Namen, ihre Orts- und Landesinformationen aufgeführt.

Abbildung 9: Für diese Lieferanten aus den USA sind Ihre Informationen zu Name, Ort und Land aufgeführt (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, die Stadt und das Land jedes Anbieters in den USA anzeigen. Es fehlt jedoch immer noch eine Spalte mit Optionsfeldern. Leider enthält 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 kann davon ausgegangen werden, dass die gewünschte Benutzeroberfläche implementiert werden kann, indem ein RadioButton-Websteuerelement zu ItemTemplate einem TemplateField hinzugefügt wird. Dadurch wird zwar jeder Zeile des GridView-Steuerelements ein einzelnes Optionsfeld hinzugefügt, die Optionsfelder können jedoch nicht gruppiert werden und schließen sich daher nicht gegenseitig aus. Das heißt, ein Endbenutzer kann mehrere Optionsfelder gleichzeitig aus der GridView auswählen.

Obwohl die Verwendung eines TemplateField-Steuerelements von RadioButton-Websteuerelementen nicht die funktionalität bietet, die wir benötigen, sollten wir diesen Ansatz implementieren, da es sich lohnt, zu untersuchen, warum die resultierenden Optionsfelder nicht gruppiert sind. Fügen Sie zunächst der Suppliers GridView ein TemplateField hinzu, sodass es das feld ganz links ist. 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 TemplateFields ItemTemplate (siehe Abbildung 10). Legen Sie die RadioButton-Eigenschaft ID auf und die GroupName -Eigenschaft auf SuppliersGroupRowSelector fest.

Hinzufügen eines RadioButton-Websteuerelements zur ItemTemplate

Abbildung 10: Hinzufügen eines RadioButton-Websteuerelements zum ItemTemplate (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nachdem Sie diese Ergänzungen über die Designer gemacht haben, sollte Ihr GridView-Markup in etwa 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 wird GroupName verwendet, um eine Reihe von Optionsfeldern zu gruppieren. Alle RadioButton-Steuerelemente mit demselben GroupName Wert gelten als gruppiert. 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 an name . Der Browser untersucht die Optionsfeldattribute name , um die Optionsfeldgruppierungen zu bestimmen.

Wenn das RadioButton-Websteuerelement hinzugefügt wird ItemTemplate, 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 sie wie in Abbildung 11 dargestellt alle Zeilen auswählen können.

Die GridView-Optionsfelder sind nicht gruppiert.

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, ist, dass sich ihre gerenderten name Attribute unterscheiden, obwohl sie dieselbe GroupName Eigenschaftseinstellung haben. Um diese Unterschiede zu sehen, führen Sie im Browser eine Ansicht/Quelle aus, und untersuchen 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 das name - id als auch das -Attribut nicht die exakten Werte sind, wie im Eigenschaftenfenster angegeben, sondern mit einer Reihe anderer ID Werte vorangestellt sind. Die zusätzlichen ID Werte, die an der Vorderseite des gerenderten id und name -Attributs hinzugefügt werden, sind die ID s der übergeordneten Optionsfelder, die IDGridViewRow GridViews ID, die Inhaltssteuerelemente IDund die WebFormulare ID. Diese ID s werden hinzugefügt, sodass jedes gerenderte Websteuerelement in GridView über einen eindeutigen id Wert und name verfügt.

Jedes gerenderte Steuerelement benötigt ein anderes name , da id der Browser jedes Steuerelement auf clientseitiger Seite eindeutig identifiziert und wie er dem Webserver identifiziert, welche Aktion oder Änderung beim Postback aufgetreten ist. Angenommen, wir möchten serverseitigen Code immer dann ausführen, wenn ein aktivierter RadioButton-Status geändert wurde. Dies können Sie erreichen, indem Sie die RadioButton-Eigenschaft AutoPostBack auf true festlegen und einen Ereignishandler für das CheckChanged Ereignis erstellen. Wenn jedoch die gerenderten name Werte und id für alle Optionsfelder identisch waren, konnten wir beim Postback nicht ermitteln, auf welche bestimmte RadioButton-Taste geklickt wurde.

Kurz gesagt, wir können keine Spalte mit Optionsfeldern in einem GridView-Steuerelement mithilfe des RadioButton-Websteuerelements erstellen. 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 nicht gruppiert 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 in GridView ordnungsgemäß zu gruppieren, müssen wir das Markup der Optionsfelder manuell in das ItemTemplateeinfügen. Jedes Optionsfeld benötigt dasselbe name Attribut, sollte jedoch ein eindeutiges id Attribut aufweisen (falls wir über clientseitiges Skript auf ein Optionsfeld 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 checked Attribut dem einen ausgewählten Optionsfeld hinzugefügt wird. Andernfalls werden die Optionsfelder, nachdem der Benutzer eine Auswahl getroffen und die Beiträge zurückgibt, in ihren Standardzustand zurückkehren (alle nicht ausgewählt).

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 durchzufü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 in etwa wie folgt aussehen:

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

Hier und GetRadioButtonValue sind Methoden, GetUniqueRadioButton die in der CodeBehind-Klasse definiert sind, die die entsprechenden id Attributwerte und value für jedes Optionsfeld zurückgegeben haben. Dieser Ansatz eignet sich 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 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 zurückgeboundt wird), und daher wird die Funktion, die das checked Attribut festlegt, beim Postback nicht aufgerufen. Es ist ein ziemlich subtiles Problem und etwas außerhalb des Rahmens dieses Artikels, also werde ich es hier belassen. Ich ermutige Sie jedoch, den oben genannten Ansatz zu versuchen und ihn bis zu dem Punkt durchzuarbeiten, an dem Sie hängen bleiben. Eine solche Übung bringt Sie zwar nicht näher an eine funktionierende Version heran, trägt jedoch dazu bei, ein tieferes Verständnis der 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 Tutorial verwenden werden, besteht darin, der Vorlage ein Literal-Steuerelement hinzuzufügen. Anschließend kann im GridView-Ereignishandler RowCreatedRowDataBound programmgesteuert auf das Literal-Steuerelement zugegriffen werden, und seine Text Eigenschaft ist auf das auszustrahlende Markup festgelegt.

Entfernen Sie zunächst radioButton aus dem TemplateField-Element ItemTemplate, und ersetzen Sie es durch ein Literal-Steuerelement. Legen Sie das Literal-Steuerelement s ID auf fest RadioButtonMarkup.

Hinzufügen eines Literalsteuerelements zur ItemTemplate

Abbildung 12: Hinzufügen eines Literalsteuerelements zu (ItemTemplateKlicken Sie hier, 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 für jede hinzugefügte Zeile einmal ausgelöst, unabhängig davon, ob die Daten an gridView rebound werden oder nicht. Das bedeutet, dass selbst bei einem Postback, wenn die Daten aus dem Ansichtszustand neu geladen werden, das RowCreated Ereignis 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 wir es mit einer Datenzeile zu tun haben. 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 SuppliersGroupfestgelegt ist, dessen id Attribut auf RowSelectorXfestgelegt ist, wobei X der Index der GridView-Zeile ist und dessen value Attribut auf den Index der GridView-Zeile festgelegt ist.

protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Grab a reference to the Literal control
        Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup");
        // 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);
    }
}

Wenn eine GridView-Zeile ausgewählt wird und ein Postback erfolgt, sind wir an der des SupplierID ausgewählten Lieferanten interessiert. Daher könnte man denken, dass der Wert jedes Optionsfelds 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 SupplierIDverarbeiten. Unsere GridView listet beispielsweise nur die Lieferanten in den USA auf. Wenn die SupplierID jedoch direkt über das Optionsfeld übergeben wird, was soll verhindern, dass ein verschmittiger Benutzer den wert bearbeitet, der SupplierID beim Postback zurückgesendet wird? Wenn Sie den Zeilenindex als valueverwenden 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.

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 rückgängig machen in ihren Ursprünglichen Zustand (d. a. 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 auftritt, 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 bereit, die die Formularvariablen darstellt. 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 gridView ist SuppliersGroup, sendet der Browser SuppliersGroup=valueOfSelectedRadioButton beim Zurückschicken der Webseite zurück an den Webserver (zusammen mit den anderen Formularfeldern). Auf diese Informationen kann dann über die Request.Form -Eigenschaft mit zugegriffen werden: Request.Form["SuppliersGroup"].

Da der ausgewählte Optionsfeldindex nicht nur im Ereignishandler, sondern in den RowCreatedClick Ereignishandlern für die Button-Websteuerelemente bestimmt werden muss, 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 int SuppliersSelectedIndex
{
    get
    {
        if (string.IsNullOrEmpty(Request.Form["SuppliersGroup"]))
            return -1;
        else
            return Convert.ToInt32(Request.Form["SuppliersGroup"]);
    }
}

Nachdem diese Eigenschaft hinzugefügt wurde, wissen wir, dass das checked="checked" Markup im RowCreated Ereignishandler hinzugefügt wird, wenn SuppliersSelectedIndex gleich e.Row.RowIndexist. Aktualisieren Sie den Ereignishandler, um diese Logik einzuschließen:

protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Grab a reference to the Literal control
        Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup");
        // 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)
            output.Text += @" checked="checked"";
        // Add the closing tag
        output.Text += " />";
    }
}

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 wird, ändern Sie einfach die if (SuppliersSelectedIndex == e.Row.RowIndex) -Anweisung in die folgende: if (SuppliersSelectedIndex == e.Row.RowIndex || (!Page.IsPostBack && e.Row.RowIndex == 0)).

An diesem Punkt haben wir dem GridView eine Spalte mit gruppierten Optionsfeldern hinzugefügt, mit der eine einzelne GridView-Zeile ausgewählt und über Postbacks hinweg gespeichert werden kann. Als Nächstes zeigen wir die Vom ausgewählten Lieferanten bereitgestellten Produkte an. In Schritt 4 erfahren Sie, wie Sie den Benutzer auf eine andere Seite umleiten und die ausgewählte SupplierIDsenden. In Schritt 5 erfahren Sie, wie Sie die produkte des ausgewählten Lieferanten in einer GridView auf derselben Seite anzeigen.

Hinweis

Anstatt ein TemplateField (der Fokus dieses langen Schritts 3) zu verwenden, 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, und die Replikation der Funktionalität auf anderen Webseiten und anderen Webanwendungen würde erheblich vereinfacht.

Wenn Sie jedoch jemals benutzerdefinierte, kompilierte Steuerelemente in ASP.NET erstellt haben, wissen Sie, dass dies eine menge Beinarbeit erfordert und eine Vielzahl von Feinheiten und Randfällen mit sich bringt, die sorgfältig behandelt werden müssen. Daher verzichten wir vorerst auf die Implementierung einer Spalte von 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 ausgewählten Produkte des Lieferanten auf einer separaten Seite

Nachdem der Benutzer eine GridView-Zeile ausgewählt hat, müssen die produkte des ausgewählten Lieferanten angezeigt werden. In einigen Fällen möchten wir diese Produkte möglicherweise auf einer separaten Seite anzeigen, in anderen fällen ziehen wir es möglicherweise 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 an, wie Sie eine GridView zu hinzufügen, um RadioButtonField.aspx die Produkte des ausgewählten Lieferanten anzuzeigen.

Derzeit gibt es zwei Button Web-Steuerelemente auf der Seite ListProducts und SendToProducts. Wenn auf die SendToProducts Schaltfläche geklickt wird, möchten wir den Benutzer an ~/Filtering/ProductsForSupplierDetails.aspxsenden. 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. Die entsprechende SupplierID kann aus der GridView-Sammlung DataKeys abgerufen werden, und der Benutzer kann dann mit Response.Redirect("url")an gesendet ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID werden.

protected void SendToProducts_Click(object sender, EventArgs e)
{
    // Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
    int supplierID = 
        Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value);
    Response.Redirect(
        "~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" 
        + supplierID);
    }
}

Dieser Code funktioniert wunderbar, solange eines der Optionsfelder aus 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, SuppliersSelectedIndex wird -1eine Ausnahme ausgelöst, da -1 sich außerhalb des Indexbereichs der DataKeys Auflistung befindet. Dies ist jedoch kein Problem, wenn Sie sich entschieden haben, den RowCreated Ereignishandler wie in Schritt 3 beschrieben zu aktualisieren, sodass das erste Optionsfeld in gridView anfänglich ausgewählt wird.

Fügen Sie der Seite oberhalb von -1GridView ein Label Web-Steuerelement hinzu, um den SuppliersSelectedIndex Wert zu berücksichtigen. Legen Sie die ID -Eigenschaft auf ChooseSupplierMsgfest, die CssClass -Eigenschaft auf Warning, die EnableViewState -Eigenschaft und Visible die -Eigenschaft auf false, und die - 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.cssdefiniert. Durch Festlegen der EnableViewState Eigenschaften und Visible auf falsewird die Bezeichnung nur für die Postbacks gerendert, bei denen die Eigenschaft des Steuerelements Visible programmgesteuert auf truefestgelegt ist.

Hinzufügen eines Label-Websteuerelements über gridView

Abbildung 13: Hinzufügen eines Label-Websteuerelements über gridView (Klicken Sie hier, um ein Bild in voller Größe anzuzeigen)

Erweitern Sie als Nächstes den Click Ereignishandler, um die ChooseSupplierMsg Bezeichnung anzuzeigen, wenn SuppliersSelectedIndex kleiner als 0 (null) ist, und leiten Sie den Benutzer andernfalls zu ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID um.

protected void SendToProducts_Click(object sender, EventArgs e)
{
    // make sure one of the radio buttons has been selected
    if (SuppliersSelectedIndex < 0)
        ChooseSupplierMsg.Visible = true;
    else
    {
        // Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
        int supplierID = 
            Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value);
        Response.Redirect(
            "~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" 
            + supplierID);
    }
}

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, wird hier 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 bereitgestellten Produkte aufgeführt sind. Abbildung 15 zeigt die ProductsForSupplierDetails.aspx Seite, auf der der Lieferant von Bigfoot Breweries ausgewählt wurde.

Die ChooseSupplierMsg-Bezeichnung wird angezeigt, wenn kein Lieferant ausgewählt ist.

Abbildung 14: Die ChooseSupplierMsg Bezeichnung wird angezeigt, wenn kein Lieferant ausgewählt ist (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Die Produkte des ausgewählten Lieferanten werden in ProductsForSupplierDetails.aspx

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 produkte des ausgewählten Lieferanten auf derselben Seite

In Schritt 4 haben wir gesehen, wie der Benutzer auf 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 RadioButtonField.aspx die Produkte des ausgewählten Lieferanten anzuzeigen.

Da diese GridView der Produkte nur angezeigt werden soll, wenn ein Lieferant ausgewählt wurde, fügen Sie ein Panel-Websteuerelement unter der Suppliers GridView hinzu, und legen Sie es ID auf ProductsBySupplierPanel und seine Visible Eigenschaft auf falsefest. Fügen Sie im Bereich 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 ProductsBySupplierDataSourcezu binden.

Binden des ProductsBySupplier GridView an eine neue ObjectDataSource

Abbildung 16: Binden der ProductsBySupplier GridView an ein neues ObjectDataSource (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Konfigurieren Sie als Nächstes die ObjectDataSource, um die ProductsBLL -Klasse zu verwenden. Da wir nur die vom ausgewählten Lieferanten bereitgestellten Produkte abrufen möchten, geben Sie an, dass die ObjectDataSource die GetProductsBySupplierID(supplierID) Methode aufrufen soll, um die Daten abzurufen. Wählen Sie in den Dropdownlisten auf den Registerkarten UPDATE, INSERT und DELETE die Option (Keine) aus.

Konfigurieren der ObjectDataSource für die Verwendung der GetProductsBySupplierID(supplierID)-Methode

Abbildung 17: Konfigurieren der ObjectDataSource für die Verwendung der GetProductsBySupplierID(supplierID) -Methode (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Legen Sie die Drop-Down Listen in den Registerkarten UPDATE, INSERT und DELETE auf (Keine) fest.

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 uns der Assistent Datenquelle erstellen auf, die Quelle für den Wert des Parameters anzugeben.

Wir haben hier eine Reihe von Optionen, um die Quelle des Werts des Parameters anzugeben. Wir können das Standardobjekt Parameter verwenden und den Wert der SuppliersSelectedIndex -Eigenschaft programmgesteuert der Parameter s-Eigenschaft DefaultValue im ObjectDataSource-Ereignishandler Selecting zuweisen. Im Tutorial Programmgesteuertes Festlegen der Parameterwerte von ObjectDataSource finden Sie eine Aktualisierung zum programmgesteuerten Zuweisen von Werten zu den Parametern von ObjectDataSource.

Alternativ können wir einen ControlParameter verwenden und auf die Eigenschaft GridView SuppliersverweisenSelectedValue (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 GridView-Eigenschaft SelectedIndex programmgesteuert auf die ausgewählte Zeile festlegen, wenn auf die ListProducts Schaltfläche geklickt wird. Als zusätzlichen Vorteil übernimmt SelectedRowStyle der SelectedIndexausgewählte Datensatz das im DataWebControls Design definierte (gelber Hintergrund).

Verwenden eines ControlParameter zum Angeben des GridView-Werts SelectedValue als Parameterquelle

Abbildung 19: Verwenden eines ControlParameter zum Angeben des GridView-Werts SelectedValue als Parameterquelle (Klicken, 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 , ProductNameCategoryNameund 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 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 und SelectedSuppliersIndex die ProductsBySupplierPanel Panel-Eigenschaft Visible auf true festlegen, wenn auf die ListProducts Schaltfläche 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 void ListProducts_Click(object sender, EventArgs e)
{
    // make sure one of the radio buttons has been selected
    if (SuppliersSelectedIndex < 0)
    {
        ChooseSupplierMsg.Visible = true;
        ProductsBySupplierPanel.Visible = false;
    }
    else
    {
        // Set the GridView's SelectedIndex
        Suppliers.SelectedIndex = SuppliersSelectedIndex;
        // Show the ProductsBySupplierPanel panel
        ProductsBySupplierPanel.Visible = true;
    }
}

Wenn kein Lieferant in der GridView ausgewählt wurde, wird die ChooseSupplierMsg Bezeichnung angezeigt und der ProductsBySupplierPanel Bereich ausgeblendet. Andernfalls wird, wenn ein Lieferant ausgewählt wurde, angezeigt ProductsBySupplierPanel , und die GridView-Eigenschaft SelectedIndex wird aktualisiert.

Abbildung 20 zeigt die Ergebnisse, nachdem der Lieferant der Bigfoot-Brauereien ausgewählt wurde und auf die Schaltfläche Produkte auf Seite anzeigen geklickt wurde.

Die von Bigfoot Brauereien gelieferten Produkte sind auf der gleichen Seite aufgeführt

Abbildung 20: Die von Bigfoot Breweries gelieferten Produkte werden 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 erläutert, können Datensätze aus einer GridView mit einem CommandField ausgewählt werden, dessen ShowSelectButton Eigenschaft auf truefestgelegt ist. Aber das CommandField zeigt seine Schaltflächen entweder als reguläre Drucktasten, Links oder Bilder an. Eine alternative Benutzeroberfläche für die Zeilenauswahl besteht darin, ein Optionsfeld oder Kontrollkästchen in jeder GridView-Zeile bereitzustellen. In diesem Tutorial haben wir untersucht, wie Sie eine Spalte mit Optionsfeldern hinzufügen.

Leider ist das Hinzufügen einer Spalte mit Optionsfeldern nicht so einfach oder einfach, wie man erwarten könnte. Es gibt kein integriertes RadioButtonField, das per Mausklick 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 sie entweder eine benutzerdefinierte DataControlField Klasse erstellen oder während RowCreated des Ereignisses den entsprechenden HTML-Code in ein TemplateField-Element einfügen.

Nachdem wir uns mit dem Hinzufügen einer Spalte mit Optionsfeldern beschäftigt haben, sollten wir uns mit dem Hinzufügen einer Spalte mit Kontrollkästchen befassen. 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 aus 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 Stunden. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderen 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 anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.