Share via


Hinzufügen von Schaltflächen zu einem GridView-Steuerelement und Zuweisen von Funktionen für diese Schaltflächen (C#)

von Scott Mitchell

PDF herunterladen

In diesem Tutorial erfahren Sie, wie Sie benutzerdefinierte Schaltflächen sowohl einer Vorlage als auch den Feldern eines GridView- oder DetailsView-Steuerelements hinzufügen. Insbesondere erstellen wir eine Schnittstelle, die über eine FormView verfügt, die es dem Benutzer ermöglicht, die Lieferanten zu durchlaufen.

Einführung

Obwohl viele Berichtsszenarien schreibgeschützten Zugriff auf die Berichtsdaten beinhalten, ist es nicht ungewöhnlich, dass Berichte die Möglichkeit enthalten, Aktionen basierend auf den angezeigten Daten auszuführen. In der Regel umfasste dies das Hinzufügen eines Button-, LinkButton- oder ImageButton-Websteuerelements mit jedem Datensatz, der im Bericht angezeigt wurde, der beim Klicken ein Postback verursacht und serverseitigen Code aufruft. Das Bearbeiten und Löschen der Daten auf Datensatzbasis ist das häufigste Beispiel. Wie wir ab dem Tutorial Übersicht über das Einfügen, Aktualisieren und Löschen von Daten gesehen haben, ist das Bearbeiten und Löschen so üblich, dass die Steuerelemente GridView, DetailsView und FormView solche Funktionen unterstützen können, ohne dass eine einzige Codezeile geschrieben werden muss.

Zusätzlich zu den Schaltflächen Bearbeiten und Löschen können die Steuerelemente GridView, DetailsView und FormView auch Schaltflächen, LinkButtons oder ImageButtons enthalten, die beim Klicken benutzerdefinierte serverseitige Logik ausführen. In diesem Tutorial erfahren Sie, wie Sie benutzerdefinierte Schaltflächen sowohl einer Vorlage als auch den Feldern eines GridView- oder DetailsView-Steuerelements hinzufügen. Insbesondere erstellen wir eine Schnittstelle, die über eine FormView verfügt, die es dem Benutzer ermöglicht, die Lieferanten zu durchlaufen. Für einen bestimmten Lieferanten zeigt die FormView Informationen zum Lieferanten zusammen mit einem Button-Websteuerelement an, das, wenn darauf geklickt, alle zugehörigen Produkte als nicht mehr verfügbar markiert. Darüber hinaus listet ein GridView-Objekt die vom ausgewählten Lieferanten bereitgestellten Produkte auf, wobei jede Zeile Die Schaltflächen "Preiserhöhung" und "Rabattpreis" enthält, die das Produkt UnitPrice bei Klick um 10 % erhöhen oder verringern (siehe Abbildung 1).

Sowohl die FormView- als auch die GridView-Schaltflächen enthalten benutzerdefinierte Aktionen.

Abbildung 1: Sowohl die Schaltflächen FormView als auch GridView enthalten, die benutzerdefinierte Aktionen ausführen (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 1: Hinzufügen der Schaltflächentutorial-Webseiten

Bevor wir uns mit dem Hinzufügen benutzerdefinierter Schaltflächen befassen, nehmen wir uns zunächst einen Moment Zeit, um die ASP.NET Seiten in unserem Websiteprojekt zu erstellen, die wir für dieses Tutorial benötigen. Fügen Sie zunächst einen neuen Ordner mit dem Namen hinzu CustomButtons. Fügen Sie als Nächstes die folgenden zwei ASP.NET Seiten zu diesem Ordner hinzu, und stellen Sie sicher, dass sie jede Seite der Site.master master-Seite zuordnen:

  • Default.aspx
  • CustomButtons.aspx

Hinzufügen der ASP.NET Pages für die Tutorials zum benutzerdefinierten Buttons-Related

Abbildung 2: Hinzufügen der ASP.NET Pages für die Tutorials zum benutzerdefinierten Buttons-Related

Wie in den anderen Ordnern Default.aspx listet der CustomButtons 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 3: Hinzufügen des SectionLevelTutorialListing.ascx Benutzersteuerelements zu (Klicken Sie hier, umDefault.aspx das Bild in voller Größe anzuzeigen)

Fügen Sie schließlich die Seiten als Einträge zur Web.sitemap Datei hinzu. Fügen Sie insbesondere das folgende Markup nach dem Auslagern und Sortieren <siteMapNode>hinzu:

<siteMapNode
    title="Adding Custom Buttons"
    description="Samples of Reports that Include Buttons for Performing
                  Server-Side Actions"
    url="~/CustomButtons/Default.aspx">
    <siteMapNode
        title="Using ButtonFields and Buttons in Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons as ButtonFields or within templates."
        url="~/CustomButtons/CustomButtons.aspx" />
</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 Websiteübersicht enthält jetzt den Eintrag für das Tutorial zu benutzerdefinierten Schaltflächen.

Abbildung 4: Die Websiteübersicht enthält jetzt den Eintrag für das Tutorial zu benutzerdefinierten Schaltflächen.

Schritt 2: Hinzufügen einer FormView, die den Lieferanten Listen

Beginnen wir mit diesem Tutorial, indem wir die FormView hinzufügen, die die Lieferanten auflistet. Wie in der Einführung erläutert, ermöglicht diese FormView dem Benutzer, die Lieferanten zu durchlaufen und die vom Lieferanten bereitgestellten Produkte in einer GridView anzuzeigen. Darüber hinaus enthält diese FormView eine Schaltfläche, die, wenn sie angeklickt wird, alle Produkte des Lieferanten als nicht mehr verfügbar markiert. Bevor wir uns mit dem Hinzufügen der benutzerdefinierten Schaltfläche zur FormView befassen, erstellen wir zunächst nur die FormView, damit die Lieferanteninformationen angezeigt werden.

Öffnen Sie zunächst die CustomButtons.aspx Seite im CustomButtons Ordner. Fügen Sie der Seite eine FormView hinzu, indem Sie sie aus der Toolbox auf die Designer ziehen, und legen Sie die ID -Eigenschaft auf festSuppliers. Wählen Sie im Smarttag von FormView aus, um eine neue ObjectDataSource mit dem Namen SuppliersDataSourcezu erstellen.

Erstellen einer neuen ObjectDataSource mit dem Namen SuppliersDataSource

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

Konfigurieren Sie diese neue ObjectDataSource so, dass sie Abfragen von der -Methode der SuppliersBLL -Klasse GetSuppliers() abfragt (siehe Abbildung 6). Da diese FormView keine Schnittstelle zum Aktualisieren der Lieferanteninformationen bereitstellt, wählen Sie in der Dropdownliste auf der Registerkarte UPDATE die Option (Keine) aus.

Konfigurieren der Datenquelle für die Verwendung der GetSuppliers()-Methode der SuppliersBLL-Klasse

Abbildung 6: Konfigurieren der Datenquelle für die Verwendung der -Methode der SuppliersBLL Klasse GetSuppliers() (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nach dem Konfigurieren der ObjectDataSource generiert Visual Studio ein InsertItemTemplate, EditItemTemplateund ItemTemplate für formView. Entfernen Sie und InsertItemTemplateEditItemTemplate , und ändern Sie die ItemTemplate , sodass nur der Firmenname und die Telefonnummer des Lieferanten angezeigt werden. Aktivieren Sie abschließend die Pagingunterstützung für formView, indem Sie das Kontrollkästchen Paging aktivieren über das Smarttag aktivieren (oder indem Sie die AllowPaging -Eigenschaft auf Truefestlegen). Nach diesen Änderungen sollte das deklarative Markup Ihrer Seite in etwa wie folgt aussehen:

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False" AllowPaging="True">
    <ItemTemplate>
        <h3>
            <asp:Label ID="CompanyName" runat="server"
                Text='<%# Bind("CompanyName") %>' />
        </h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
    </ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>

Abbildung 7 zeigt die CustomButtons.aspx Seite, wenn sie über einen Browser angezeigt wird.

Die FormView Listen die Felder

Abbildung 7: Die FormView Listen die CompanyName Felder und Phone aus dem derzeit ausgewählten Lieferanten (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 3: Hinzufügen eines GridView-Steuerelements, das die Produkte des ausgewählten Lieferanten Listen

Bevor wir der FormView-Vorlage die Schaltfläche Alle Produkte beenden hinzufügen, fügen wir zunächst eine GridView unter der FormView hinzu, die die vom ausgewählten Lieferanten bereitgestellten Produkte auflistet. Fügen Sie dazu der Seite ein GridView-Element hinzu, legen Sie die ID -Eigenschaft auf SuppliersProductsfest, und fügen Sie eine neue ObjectDataSource mit dem Namen hinzu SuppliersProductsDataSource.

Erstellen einer neuen ObjectDataSource mit dem Namen SuppliersProductsDataSource

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

Konfigurieren Sie diese ObjectDataSource so, dass die Methode der ProductsBLL-Klasse GetProductsBySupplierID(supplierID) verwendet wird (siehe Abbildung 9). Diese GridView ermöglicht zwar die Anpassung des Preises eines Produkts, verwendet jedoch nicht die integrierten Bearbeitungs- oder Löschfunktionen aus gridView. Daher können wir die Dropdownliste für die Registerkarten UPDATE, INSERT und DELETE der ObjectDataSource auf (Keine) festlegen.

Konfigurieren der Datenquelle für die Verwendung der GetProductsBySupplierID(supplierID)-Methode der ProductsBLL-Klasse

Abbildung 9: Konfigurieren der Datenquelle für die Verwendung der -Methode der ProductsBLL Klasse GetProductsBySupplierID(supplierID) (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Da die GetProductsBySupplierID(supplierID) -Methode einen Eingabeparameter akzeptiert, fordert uns der ObjectDataSource-Assistent zur Eingabe der Quelle dieses Parameterwerts auf. Um den SupplierID Wert aus der FormView zu übergeben, legen Sie die Dropdownliste Parameterquelle auf Control und die Dropdownliste ControlID auf Suppliers (die ID der in Schritt 2 erstellten FormView) fest.

Geben Sie an, dass der supplierID-Parameter aus dem Formularansicht-Steuerelement für Lieferanten stammen soll.

Abbildung 10: Angeben, dass der supplierID Parameter aus dem Suppliers FormView-Steuerelement stammen soll (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nach Abschluss des ObjectDataSource-Assistenten enthält gridView ein BoundField- oder CheckBoxField-Element für jedes der Datenfelder des Produkts. Kürzen wir dies, um nur die ProductName BoundFields Discontinued und UnitPrice das CheckBoxField anzuzeigen. Außerdem formatieren wir das UnitPrice BoundField so, dass sein Text als Währung formatiert ist. Das deklarative Markup Ihres GridView- und SuppliersProductsDataSource ObjectDataSource-Markups sollte dem folgenden Markup ähneln:

<asp:GridView ID="SuppliersProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:ControlParameter ControlID="Suppliers" Name="supplierID"
            PropertyName="SelectedValue" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

An diesem Punkt zeigt unser Tutorial einen master-/Detailbericht an, mit dem der Benutzer einen Lieferanten aus der FormView oben auswählen und die von diesem Lieferanten bereitgestellten Produkte über gridView unten anzeigen kann. Abbildung 11 zeigt einen Screenshot dieser Seite, wenn Sie den Tokyo Traders-Lieferanten aus der FormView auswählen.

Die ausgewählten Lieferantenprodukte werden in GridView angezeigt.

Abbildung 11: Die Produkte des ausgewählten Lieferanten werden in GridView angezeigt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 4: Erstellen von DAL- und BLL-Methoden, um alle Produkte für einen Lieferanten einzustellen

Bevor wir der FormView eine Schaltfläche hinzufügen können, die beim Klicken alle Produkte des Lieferanten ausschaltet, müssen wir zunächst sowohl der DAL als auch der BLL eine Methode hinzufügen, die diese Aktion ausführt. Insbesondere trägt diese Methode den Namen DiscontinueAllProductsForSupplier(supplierID). Wenn auf die Schaltfläche von FormView geklickt wird, rufen wir diese Methode in der Geschäftslogikebene auf und übergeben den des ausgewählten Lieferanten SupplierID. Die BLL ruft dann die entsprechende Data Access Layer-Methode auf, die eine UPDATE Anweisung an die Datenbank ausgibt, die die Produkte des angegebenen Lieferanten eingestellt.

Wie in unseren vorherigen Tutorials verwenden wir einen Bottom-up-Ansatz, beginnend mit dem Erstellen der DAL-Methode, dann der BLL-Methode und schließlich der Implementierung der Funktionalität auf der Seite ASP.NET. Öffnen Sie das Northwind.xsd Typisierte DataSet im App_Code/DAL Ordner, und fügen Sie dem eine neue Methode hinzu (klicken Sie mit der ProductsTableAdapter rechten Maustaste auf die ProductsTableAdapter , und wählen Sie Abfrage hinzufügen aus). Dadurch wird der TableAdapter-Abfragekonfigurations-Assistent angezeigt, der uns durch den Prozess zum Hinzufügen der neuen Methode führt. Geben Sie zunächst an, dass die DAL-Methode eine Ad-hoc-SQL-Anweisung verwendet.

Erstellen der DAL-Methode mithilfe einer Ad-hoc-SQL-Anweisung

Abbildung 12: Erstellen der DAL-Methode mithilfe einer Ad-hoc-SQL-Anweisung (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Als Nächstes fragt uns der Assistent, welche Art von Abfrage erstellt werden soll. Da die DiscontinueAllProductsForSupplier(supplierID) -Methode die Products Datenbanktabelle aktualisieren muss und das Discontinued Feld für alle von dem angegebenen supplierIDbereitgestellten Produkte auf 1 festgelegt wird, müssen wir eine Abfrage erstellen, die Daten aktualisiert.

Wählen Sie den UPDATE-Abfragetyp aus.

Abbildung 13: Auswählen des UPDATE-Abfragetyps (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Auf dem nächsten Assistentenbildschirm wird die vorhandene UPDATE TableAdapter-Anweisung angezeigt, die jedes der in der Products DataTable definierten Felder aktualisiert. Ersetzen Sie diesen Abfragetext durch die folgende Anweisung:

UPDATE [Products] SET
   Discontinued = 1
WHERE SupplierID = @SupplierID

Nachdem Sie diese Abfrage eingegeben und auf Weiter geklickt haben, wird auf dem letzten Bildschirm des Assistenten nach dem Namen der neuen Methode gefragt. Verwenden Sie DiscontinueAllProductsForSupplier. Schließen Sie den Assistenten ab, indem Sie auf die Schaltfläche Fertig stellen klicken. Nach der Rückkehr zum DataSet-Designer sollte in der eine neue Methode mit dem ProductsTableAdapter Namen DiscontinueAllProductsForSupplier(@SupplierID)angezeigt werden.

Benennen Sie die neue DAL-Methode DiscontinueAllProductsForSupplier.

Abbildung 14: Benennen Sie die neue DAL-Methode (Klicken Sie hier, um das bild in voller Größe anzuzeigen)DiscontinueAllProductsForSupplier

Mit der Methode, die DiscontinueAllProductsForSupplier(supplierID) in der Datenzugriffsebene erstellt wurde, besteht die nächste Aufgabe darin, die Methode in der DiscontinueAllProductsForSupplier(supplierID) Geschäftslogikebene zu erstellen. Öffnen Sie hierzu die ProductsBLL Klassendatei, und fügen Sie Folgendes hinzu:

public int DiscontinueAllProductsForSupplier(int supplierID)
{
    return Adapter.DiscontinueAllProductsForSupplier(supplierID);
}

Diese Methode ruft einfach die Methode in der DiscontinueAllProductsForSupplier(supplierID) DAL auf und übergibt den angegebenen supplierID Parameterwert. Wenn es Geschäftsregeln gab, die nur die Einstellung der Produkte eines Lieferanten unter bestimmten Umständen erlaubten, sollten diese Regeln hier, in der BLL, umgesetzt werden.

Hinweis

Im Gegensatz zu den UpdateProduct Überladungen in der ProductsBLL -Klasse enthält die DiscontinueAllProductsForSupplier(supplierID) Methodensignatur nicht das DataObjectMethodAttribute Attribut (<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, Boolean)>). Dies schließt die DiscontinueAllProductsForSupplier(supplierID) Methode aus der Dropdownliste "Datenquelle konfigurieren" des Assistenten "Datenquelle konfigurieren" auf der Registerkarte UPDATE aus. Dieses Attribut habe ich weggelassen, da wir die DiscontinueAllProductsForSupplier(supplierID) -Methode direkt von einem Ereignishandler auf unserer ASP.NET-Seite aufrufen.

Schritt 5: Hinzufügen einer Schaltfläche Zum Beenden aller Produkte zur FormView

Nachdem die DiscontinueAllProductsForSupplier(supplierID) Methode in der BLL und DAL abgeschlossen ist, besteht der letzte Schritt zum Hinzufügen der Möglichkeit, alle Produkte für den ausgewählten Lieferanten einzustellen, darin, dem FormView-Steuerelement ItemTemplateein Button-Websteuerelement hinzuzufügen. Fügen Wir eine solche Schaltfläche unter der Telefonnummer des Anbieters mit dem Schaltflächentext "Alle Produkte beenden" und einem ID Eigenschaftswert von hinzu DiscontinueAllProductsForSupplier. Sie können dieses Schaltflächen-Websteuerelement über die Designer hinzufügen, indem Sie im Smarttag der FormView auf den Link Vorlagen bearbeiten klicken (siehe Abbildung 15) oder direkt über die deklarative Syntax.

Hinzufügen eines Websteuerelements für die Schaltfläche

Abbildung 15: Hinzufügen eines Websteuerelements mit der Schaltfläche "Alle Produkte beenden" zu den Formularansichten ItemTemplate (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Wenn ein Benutzer, der die Seite besucht, auf die Schaltfläche klickt, wird ein Postback ausgeführt, und das FormView-EreignisItemCommand wird ausgelöst. Um benutzerdefinierten Code als Reaktion auf diese Schaltfläche auszuführen, auf die geklickt wird, können wir einen Ereignishandler für dieses Ereignis erstellen. Verstehen Sie jedoch, dass das ItemCommand Ereignis immer dann ausgelöst wird, wenn auf ein Button-, LinkButton- oder ImageButton-Websteuerelement in der FormView geklickt wird. Das bedeutet, dass das Ereignis ausgelöst wird, ItemCommand wenn der Benutzer in der FormView von einer Seite zur anderen wechselt. Dasselbe gilt, wenn der Benutzer in einer FormView auf Neu, Bearbeiten oder Löschen klickt, die das Einfügen, Aktualisieren oder Löschen unterstützt.

Da die ItemCommand Schaltfläche unabhängig davon ausgelöst wird, auf welche Schaltfläche geklickt wird, benötigen wir im Ereignishandler eine Möglichkeit, um zu bestimmen, ob auf die Schaltfläche Alle Produkte beenden geklickt wurde oder ob es sich um eine andere Schaltfläche handelt. Um dies zu erreichen, können wir die Eigenschaft des CommandName Button-Websteuerelements auf einen identifizierenden Wert festlegen. Wenn auf die Schaltfläche geklickt wird, wird dieser CommandName Wert an den ItemCommand Ereignishandler übergeben, sodass wir ermitteln können, ob die Schaltfläche "Alle Produkte beenden" die Schaltfläche war, auf die geklickt wurde. Legen Sie die Eigenschaft der Schaltfläche "Alle Produkte beenden" CommandName auf "DiscontinueProducts" fest.

Abschließend verwenden wir ein clientseitiges Bestätigungsdialogfeld, um sicherzustellen, dass der Benutzer die Produkte des ausgewählten Lieferanten wirklich einstellen möchte. Wie wir im Tutorial Hinzufügen von Client-Side Bestätigung beim Löschen gezeigt haben, kann dies mit etwas JavaScript erreicht werden. Legen Sie insbesondere die OnClientClick-Eigenschaft des Button-Websteuerelements auf fest. return confirm('This will mark _all_ of this supplier\'s products as discontinued. Are you certain you want to do this?');

Nach diesen Änderungen sollte die deklarative Syntax von FormView wie folgt aussehen:

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False"
    AllowPaging="True">
    <ItemTemplate>
        <h3><asp:Label ID="CompanyName" runat="server"
            Text='<%# Bind("CompanyName") %>'></asp:Label></h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
        <br />
        <asp:Button ID="DiscontinueAllProductsForSupplier" runat="server"
            CommandName="DiscontinueProducts" Text="Discontinue All Products"
            OnClientClick="return confirm('This will mark _all_ of this supplier\'s
                products as discontinued. Are you certain you want to do this?');" />
    </ItemTemplate>
</asp:FormView>

Erstellen Sie als Nächstes einen Ereignishandler für das FormView-Ereignis ItemCommand . In diesem Ereignishandler müssen wir zuerst ermitteln, ob auf die Schaltfläche Alle Produkte beenden geklickt wurde. Wenn ja, möchten wir eine instance der -Klasse erstellen und deren ProductsBLLDiscontinueAllProductsForSupplier(supplierID) -Methode aufrufen, wobei die SupplierID der ausgewählten FormView übergeben wird:

protected void Suppliers_ItemCommand(object sender, FormViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("DiscontinueProducts") == 0)
    {
        // The "Discontinue All Products" Button was clicked.
        // Invoke the ProductsBLL.DiscontinueAllProductsForSupplier(supplierID) method
        // First, get the SupplierID selected in the FormView
        int supplierID = (int)Suppliers.SelectedValue;
        // Next, create an instance of the ProductsBLL class
        ProductsBLL productInfo = new ProductsBLL();
        // Finally, invoke the DiscontinueAllProductsForSupplier(supplierID) method
        productInfo.DiscontinueAllProductsForSupplier(supplierID);
    }
}

Beachten Sie, dass auf den SupplierID des aktuell ausgewählten Lieferanten in der FormView über die FormView-Eigenschaft SelectedValuezugegriffen werden kann. Die SelectedValue -Eigenschaft gibt den ersten Datenschlüsselwert für den Datensatz zurück, der in der FormView angezeigt wird. Die FormView-EigenschaftDataKeyNames, die die Datenfelder angibt, aus denen die Datenschlüsselwerte abgerufen werden, wurde von Visual Studio automatisch auf SupplierID festgelegt, wenn die ObjectDataSource wieder in Schritt 2 an die FormView gebunden wurde.

Nehmen Sie sich nach dem Erstellen des ItemCommand Ereignishandlers einen Moment Zeit, um die Seite zu testen. Navigieren Sie zum Lieferanten der Cooperativa de Quesos "Las Cabras" (es ist für mich der fünfte Lieferant in der FormView). Dieser Lieferant bietet zwei Produkte an, Queso Cabrales und Queso Manchego La Pastora, die beide nicht eingestellt werden.

Stellen Sie sich vor, die Cooperativa de Quesos "Las Cabras" ist aus dem Geschäft gegangen und deshalb werden ihre Produkte eingestellt. Klicken Sie auf die Schaltfläche Alle Produkte beenden. Dadurch wird das clientseitige Bestätigungsdialogfeld angezeigt (siehe Abbildung 16).

Cooperativa de Quesos Las Cabras liefert zwei aktive Produkte

Abbildung 16: Cooperativa de Quesos Las Cabras Liefert zwei aktive Produkte (Klicken Sie hier, um das vollständige Bild anzuzeigen)

Wenn Sie im clientseitigen Bestätigungsdialogfeld auf OK klicken, wird die Formularübermittlung fortgesetzt, was zu einem Postback führt, in dem das FormView-Ereignis ItemCommand ausgelöst wird. Der von uns erstellte Ereignishandler wird dann ausgeführt, indem die DiscontinueAllProductsForSupplier(supplierID) -Methode aufgerufen und sowohl die Produkte Queso Cabrales als auch Queso Manchego La Pastora eingestellt werden.

Wenn Sie den Ansichtszustand von GridView deaktiviert haben, wird die GridView bei jedem Postback an den zugrunde liegenden Datenspeicher zurückgeführt und daher sofort aktualisiert, um widerzuspiegeln, dass diese beiden Produkte jetzt nicht mehr verfügbar sind (siehe Abbildung 17). Wenn Sie jedoch den Ansichtszustand in GridView nicht deaktiviert haben, müssen Sie die Daten nach dieser Änderung manuell an gridView binden. Um dies zu erreichen, rufen Sie einfach die GridView-Methode DataBind() direkt nach dem Aufrufen der DiscontinueAllProductsForSupplier(supplierID) -Methode auf.

Nachdem Sie auf die Schaltfläche Alle Produkte beenden geklickt haben, werden die Produkte des Lieferanten entsprechend aktualisiert.

Abbildung 17: Nachdem Sie auf die Schaltfläche Alle Produkte beenden geklickt haben, werden die Produkte des Lieferanten entsprechend aktualisiert (Klicken Sie hier, um das vollständige Bild anzuzeigen).

Schritt 6: Erstellen einer UpdateProduct-Überladung in der Geschäftslogikebene zum Anpassen des Preises eines Produkts

Wie bei der Schaltfläche Alle Produkte abbrechen in der FormView müssen wir zuerst die entsprechenden Methoden für den Datenzugriff und die Geschäftslogikebene hinzufügen, um Schaltflächen zum Erhöhen und Senken des Preises für ein Produkt in der GridView hinzuzufügen. Da wir bereits über eine Methode verfügen, die eine einzelne Produktzeile in der DAL aktualisiert, können wir diese Funktionalität bereitstellen, indem wir eine neue Überladung für die UpdateProduct Methode in der BLL erstellen.

Unsere vergangenen UpdateProduct Überladungen haben eine Kombination von Produktfeldern als skalare Eingabewerte übernommen und dann nur diese Felder für das angegebene Produkt aktualisiert. Für diese Überladung unterscheiden wir uns geringfügig von diesem Standard und übergeben stattdessen das Produkt ProductID und den Prozentsatz, um den angepasst UnitPrice werden soll (anstatt das neue, angepasste UnitPrice selbst zu übergeben). Dieser Ansatz vereinfacht den Code, den wir in die CodeBehind-Klasse der ASP.NET Seite schreiben müssen, da wir uns nicht mit der Bestimmung des aktuellen Produkts UnitPricemühen müssen.

Die UpdateProduct Überladung für dieses Tutorial ist unten dargestellt:

public bool UpdateProduct(decimal unitPriceAdjustmentPercentage, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;
    Northwind.ProductsRow product = products[0];
    // Adjust the UnitPrice by the specified percentage (if it's not NULL)
    if (!product.IsUnitPriceNull())
        product.UnitPrice *= unitPriceAdjustmentPercentage;
    // Update the product record
    int rowsAffected = Adapter.Update(product);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

Diese Überladung ruft Informationen zum angegebenen Produkt über die DAL-Methode ab GetProductByProductID(productID) . Anschließend wird überprüft, ob dem Produkt UnitPrice ein Datenbankwert NULL zugewiesen ist. Wenn dies der Grund ist, bleibt der Preis unverändert. Wenn jedoch ein Nicht-WertNULLUnitPrice vorhanden ist, aktualisiert die Methode das Produkt UnitPrice um den angegebenen Prozentsatz (unitPriceAdjustmentPercent).

Schritt 7: Hinzufügen der Schaltflächen "Erhöhen" und "Verringern" zur GridView

GridView (und DetailsView) bestehen beide aus einer Sammlung von Feldern. Zusätzlich zu BoundFields, CheckBoxFields und TemplateFields enthält ASP.NET das ButtonField, das, wie der Name schon sagt, als Spalte mit einem Button, LinkButton oder ImageButton für jede Zeile gerendert wird. Ähnlich wie bei FormView führt das Klicken auf eine beliebige Schaltfläche innerhalb der GridView-Pagingschaltflächen, Schaltflächen Bearbeiten oder Löschen, Sortieren von Schaltflächen usw. zu einem Postback und löst das GridView-EreignisRowCommand aus.

ButtonField verfügt über eine CommandName Eigenschaft, die jedem seiner Buttons-Eigenschaften CommandName den angegebenen Wert zuweist. Wie bei der FormView wird der CommandName Wert vom RowCommand Ereignishandler verwendet, um zu bestimmen, auf welche Schaltfläche geklickt wurde.

Fügen Wir der GridView zwei neue ButtonFields hinzu, eines mit einem Schaltflächentext Price +10% und der andere mit dem Text Price -10%. Um diese ButtonFields hinzuzufügen, klicken Sie im Smarttag von GridView auf den Link Spalten bearbeiten, wählen Sie den Feldtyp ButtonField in der Liste oben links aus, und klicken Sie auf die Schaltfläche Hinzufügen.

Hinzufügen von zwei ButtonFields zur GridView

Abbildung 18: Hinzufügen von zwei ButtonFields zur GridView

Verschieben Sie die beiden ButtonFields so, dass sie als die ersten beiden GridView-Felder angezeigt werden. Legen Sie als Nächstes die Text Eigenschaften dieser beiden ButtonFields auf Price +10% und Price -10% und die CommandName Eigenschaften auf IncreasePrice bzw. DecreasePrice fest. Standardmäßig rendert ein ButtonField seine Schaltflächenspalte als LinkButtons. Dies kann jedoch über die Eigenschaft von ButtonTypeButtonField geändert werden. Lassen Sie diese beiden ButtonFields als reguläre Drucktasten gerendert werden. Legen Sie daher die ButtonType -Eigenschaft auf fest Button. Abbildung 19 zeigt das Dialogfeld Felder, nachdem diese Änderungen vorgenommen wurden. folgt das deklarative Markup von GridView.

Konfigurieren der Eigenschaften ButtonFields Text, CommandName und ButtonType

Abbildung 19: Konfigurieren der Eigenschaften ButtonFieldsText, CommandName, und ButtonType

<asp:GridView ID="SuppliersProducts" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False">
    <Columns>
        <asp:ButtonField ButtonType="Button" CommandName="IncreasePrice"
            Text="Price +10%" />
        <asp:ButtonField ButtonType="Button" CommandName="DecreasePrice"
            Text="Price -10%" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

Nachdem diese ButtonFields erstellt wurden, besteht der letzte Schritt darin, einen Ereignishandler für das GridView-Ereignis RowCommand zu erstellen. Wenn dieser Ereignishandler ausgelöst wird, weil entweder auf die Schaltflächen Price +10% oder Price -10% geklickt wurde, muss der ProductID für die Zeile ermittelt werden, auf deren Schaltfläche geklickt wurde, und dann die Methode der ProductsBLL Klasse UpdateProduct aufrufen, wobei die entsprechende UnitPrice Prozentuale Anpassung zusammen mit dem ProductIDübergeben wird. Der folgende Code führt diese Aufgaben aus:

protected void SuppliersProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("IncreasePrice") == 0 ||
        e.CommandName.CompareTo("DecreasePrice") == 0)
    {
        // The Increase Price or Decrease Price Button has been clicked
        // Determine the ID of the product whose price was adjusted
        int productID =
            (int)SuppliersProducts.DataKeys[Convert.ToInt32(e.CommandArgument)].Value;
        // Determine how much to adjust the price
        decimal percentageAdjust;
        if (e.CommandName.CompareTo("IncreasePrice") == 0)
            percentageAdjust = 1.1M;
        else
            percentageAdjust = 0.9M;

        // Adjust the price
        ProductsBLL productInfo = new ProductsBLL();
        productInfo.UpdateProduct(percentageAdjust, productID);
    }
}

Um den für die Zeile zu ermitteln, auf deren ProductID Schaltfläche "Price +10%" oder "Price -10%" geklickt wurde, müssen wir die Sammlung von DataKeys GridView konsultieren. Diese Auflistung enthält die Werte der Felder, die in der DataKeyNames Eigenschaft für jede GridView-Zeile angegeben sind. Da die GridView-Eigenschaft DataKeyNames von Visual Studio beim Binden der ObjectDataSource an gridView auf ProductID festgelegt wurde, DataKeys(rowIndex).Value stellt für den angegebenen rowIndex bereitProductID.

ButtonField übergibt automatisch den rowIndex der Zeile, auf deren Schaltfläche durch den e.CommandArgument Parameter geklickt wurde. Um für die Zeile zu ermitteln, auf deren ProductID Schaltfläche Preis +10% oder Preis -10% geklickt wurde, verwenden wir folgendes: Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value).

Wenn Sie den Ansichtsstatus der GridView deaktiviert haben, wird die GridView wie bei der Schaltfläche Alle Produkte abbrechen bei jedem Postback an den zugrunde liegenden Datenspeicher zurückgebunden und daher sofort aktualisiert, um eine Preisänderung widerzuspiegeln, die beim Klicken auf eine der Schaltflächen auftritt. Wenn Sie jedoch den Ansichtszustand in GridView nicht deaktiviert haben, müssen Sie die Daten nach dieser Änderung manuell an gridView binden. Um dies zu erreichen, rufen Sie einfach die GridView-Methode DataBind() direkt nach dem Aufrufen der UpdateProduct -Methode auf.

Abbildung 20 zeigt die Seite beim Anzeigen der von Grandma Kelly's Homestead bereitgestellten Produkte. Abbildung 21 zeigt die Ergebnisse, nachdem die Schaltfläche Preis +10 % zweimal für Grandma's Boysenberry Spread und einmal die Schaltfläche Preis -10% für Northwoods Cranberry Sauce geklickt wurde.

Die GridView enthält Schaltflächen

Abbildung 20: Die GridView enthält Schaltflächen "Preis " +10 % " und "Preis " -10 %" (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Die Preise für das erste und dritte Produkt wurden über die Schaltflächen Preis +10% und Preis -10% aktualisiert.

Abbildung 21: Die Preise für das erste und dritte Produkt wurden über die Schaltflächen Preis +10% und Preis -10% aktualisiert (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Hinweis

Die GridView (und DetailsView) können auch Schaltflächen, LinkButtons oder ImageButtons zu ihren TemplateFields hinzugefügt haben. Wie beim BoundField führen diese Schaltflächen beim Klicken zu einem Postback, wodurch das GridView-Ereignis RowCommand ausgelöst wird. Beim Hinzufügen von Schaltflächen in einem TemplateField wird die Schaltfläche jedoch nicht automatisch auf den Index der Zeile festgelegt, wie dies CommandArgument bei Verwendung von ButtonFields der Fall ist. Wenn Sie den Zeilenindex der Schaltfläche ermitteln müssen, auf die innerhalb des RowCommand Ereignishandlers geklickt wurde, müssen Sie die Button-Eigenschaft CommandArgument in der deklarativen Syntax im TemplateField manuell festlegen, indem Sie Code wie folgt verwenden:
<asp:Button runat="server" ... CommandArgument='<%# ((GridViewRow) Container).RowIndex %>'.

Zusammenfassung

Die Steuerelemente GridView, DetailsView und FormView können Schaltflächen, LinkButtons oder ImageButtons enthalten. Solche Schaltflächen führen beim Klicken zu einem Postback und lösen das Ereignis in den ItemCommand Steuerelementen FormView und DetailsView sowie das RowCommand Ereignis in der GridView aus. Diese Datenwebsteuerelemente verfügen über integrierte Funktionen, um allgemeine befehlsbezogene Aktionen wie das Löschen oder Bearbeiten von Datensätzen zu verarbeiten. Wir können jedoch auch Schaltflächen verwenden, die beim Klicken mit der Ausführung unseres eigenen benutzerdefinierten Codes reagieren.

Um dies zu erreichen, müssen wir einen Ereignishandler für das ItemCommand -Ereignis oder RowCommand erstellen. In diesem Ereignishandler überprüfen wir zunächst den eingehenden CommandName Wert, um zu ermitteln, auf welche Schaltfläche geklickt wurde, und führen dann die entsprechende benutzerdefinierte Aktion aus. In diesem Tutorial haben wir erfahren, wie Sie Schaltflächen und ButtonFields verwenden, um alle Produkte für einen bestimmten Lieferanten einzustellen oder den Preis eines bestimmten Produkts um 10 % zu erhöhen oder zu senken.

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.