Freigeben über


Hinzufügen von Schaltflächen zu einem GridView-Steuerelement und Reagieren auf diese Schaltflächen (C#)

von Scott Mitchell

PDF herunterladen

In diesem Lernprogramm befassen wir uns mit dem Hinzufügen von benutzerdefinierten Schaltflächen sowohl zu einer Vorlage als auch zu den Feldern eines GridView- oder DetailsView-Steuerelements. Insbesondere erstellen wir eine Schnittstelle mit einer FormView, die es dem Benutzer ermöglicht, über die Lieferanten zu blättern.

Einführung

Während viele Berichtsszenarien nur den Zugriff zum Lesen auf die Berichtsdaten beinhalten, ist es nicht ungewöhnlich, dass Berichte die Möglichkeit bieten, Aktionen basierend auf den angezeigten Daten auszuführen. In der Regel umfasst dies das Hinzufügen eines Button-, LinkButton- oder ImageButton-Websteuerelements, das zu jedem im Bericht angezeigten Datensatz hinzugefügt wird und, wenn es angeklickt wird, einen Postback verursacht und serverseitigen Code aufruft. Das Bearbeiten und Löschen der Daten auf Datensatzbasis ist das häufigste Beispiel. Wie wir mit der Übersicht über das Lernprogramm zum Einfügen, Aktualisieren und Löschen von Daten begonnen haben, ist das Bearbeiten und Löschen von Daten so häufig, dass die Steuerelemente "GridView", "DetailsView" und "FormView" diese Funktionalität unterstützen können, ohne dass eine einzelne 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 auf eine benutzerdefinierte serverseitige Logik ausgeführt werden. In diesem Lernprogramm befassen wir uns mit dem Hinzufügen von benutzerdefinierten Schaltflächen sowohl zu einer Vorlage als auch zu den Feldern eines GridView- oder DetailsView-Steuerelements. Insbesondere erstellen wir eine Schnittstelle mit einer FormView, die es dem Benutzer ermöglicht, über die Lieferanten zu blättern. Für einen bestimmten Lieferanten zeigt FormView Informationen zum Lieferanten zusammen mit einem Button-Web-Steuerelement an, das, wenn darauf geklickt wird, alle zugehörigen Produkte als nicht mehr verfügbar markiert. Darüber hinaus listet ein GridView-Steuerelement die vom ausgewählten Lieferanten bereitgestellten Produkte auf, wobei jede Zeile die Schaltflächen "Preiserhöhung" und "Preisnachlass" enthält, die das Produkt UnitPrice auf 10 % erhöhen oder reduzieren (siehe Abbildung 1).

Sowohl formView als auch GridView enthalten Schaltflächen, die benutzerdefinierte Aktionen ausführen

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

Schritt 1: Hinzufügen der Tutorial-Webseiten für Schaltflächen

Bevor wir uns ansehen, wie sie benutzerdefinierte Schaltflächen hinzufügen, nehmen wir uns zunächst einen Moment Zeit, um die ASP.NET Seiten in unserem Websiteprojekt zu erstellen, die wir für dieses Lernprogramm benötigen. Beginnen Sie mit dem Hinzufügen eines neuen Ordners mit dem Namen CustomButtons. Fügen Sie als Nächstes die folgenden zwei ASP.NET Seiten zu diesem Ordner hinzu, und stellen Sie sicher, dass jede Seite der Gestaltungsvorlage Site.master zugeordnet wird:

  • Default.aspx
  • CustomButtons.aspx

Hinzufügen der ASP.NET-Seiten für Tutorials zu benutzerdefinierten Schaltflächen

Abbildung 2: Hinzufügen der ASP.NET Seiten für benutzerdefinierte Schaltflächenbezogene Lernprogramme

Wie in den anderen Ordnern Default.aspx werden im CustomButtons Ordner die Lernprogramme im zugehörigen Abschnitt aufgelistet. Erinnern Sie sich daran, dass das SectionLevelTutorialListing.ascx Benutzersteuerelement diese Funktionalität bereitstellt. Fügen Sie daher dieses Benutzersteuerelement zu Default.aspx hinzu, indem Sie es aus dem Projektmappen-Explorer in die Seitenentwurfsansicht ziehen.

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

Abbildung 3: Hinzufügen des SectionLevelTutorialListing.ascx Benutzersteuerelements zu Default.aspx (Klicken, um 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 der Paging- und Sortierung <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.sitemap einen Moment Zeit, um die Tutorials-Website in einem Browser anzuzeigen. Das Menü auf der linken Seite enthält jetzt Elemente für die Bearbeitung, das Einfügen und Löschen von Lernprogrammen.

Die Websiteübersicht enthält jetzt den Eintrag für das Lernprogramm für benutzerdefinierte Schaltflächen.

Abbildung 4: Die Websiteübersicht enthält jetzt den Eintrag für das Lernprogramm für benutzerdefinierte Schaltflächen.

Schritt 2: Hinzufügen einer FormView, die die Lieferanten auflistet

Beginnen wir mit diesem Lernprogramm, 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 in einer GridView bereitgestellten Produkte anzuzeigen. Darüber hinaus enthält dieses FormView-Steuerelement eine Schaltfläche, die, wenn darauf geklickt wird, alle Produkte des Lieferanten als nicht mehr eingestellt markiert. Bevor wir uns mit dem Hinzufügen der benutzerdefinierten Schaltfläche zur FormView befassen, erstellen wir zuerst die FormView, sodass die Lieferanteninformationen angezeigt werden.

Öffnen Sie zunächst die CustomButtons.aspx Seite im CustomButtons Ordner. Fügen Sie der Seite ein FormView-Steuerelement hinzu, indem Sie es aus der Toolbox auf den Designer ziehen und dessen ID Eigenschaft auf Suppliersfestlegen. Wählen Sie im Smart Tag von FormView eine neue ObjectDataSource mit dem Namen SuppliersDataSource aus.

Erstellen einer neuen ObjectDataSource namens 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 die Methode GetSuppliers() der Klasse SuppliersBLL abfragt (siehe Abbildung 6). Da dieses 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 SuppliersBLL-Klasse getSuppliers() -Methode

Abbildung 6: Konfigurieren Sie die Datenquelle, um die Methode der SuppliersBLL Klasse zu verwenden (SuppliersBLL Bild in voller Größe anzeigen, klicken Sie hier)

Nach dem Konfigurieren der ObjectDataSource generiert Visual Studio ein InsertItemTemplate, EditItemTemplateund ItemTemplate für die FormView. Entfernen Sie die InsertItemTemplate und EditItemTemplate und ändern Sie das ItemTemplate so, dass es nur den Firmennamen und die Telefonnummer des Lieferanten anzeigt. Aktivieren Sie schließlich die Paging-Unterstützung für die FormView, indem Sie das Smarttag verwenden, um das Kontrollkästchen "Paging aktivieren" zu aktivieren, oder indem Sie die AllowPaging-Eigenschaft auf True festlegen. Nach diesen Änderungen sollte das deklarative Markup Ihrer Seite 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 listet die Felder

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

Schritt 3: Hinzufügen einer GridView, die die Produkte des ausgewählten Lieferanten auflistet

Bevor wir die Schaltfläche "Alle Produkte beenden" zur Vorlage von FormView hinzufügen, fügen wir zunächst ein GridView-Element unter der FormView hinzu, das die vom ausgewählten Lieferanten bereitgestellten Produkte auflistet. Fügen Sie dazu der Seite eine GridView hinzu, legen Sie dessen ID-Eigenschaft auf SuppliersProducts fest, und fügen Sie eine neue ObjectDataSource namens SuppliersProductsDataSource hinzu.

Erstellen einer neuen ObjectDataSource named 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 GetProductsBySupplierID(supplierID) der ProductsBLL-Klasse verwendet wird (siehe Abbildung 9). Obwohl dieses GridView-Steuerelement die Anpassung des Preises eines Produkts ermöglicht, verwendet es nicht die integrierten Bearbeitungs- oder Löschfunktionen des GridView. Daher können wir die Dropdownliste auf (Keine) für die Registerkarten UPDATE, INSERT und DELETE von ObjectDataSource 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 ProductsBLL Klassesmethode GetProductsBySupplierID(supplierID) (Klicken, um das Bild in voller Größe anzuzeigen)

Da die GetProductsBySupplierID(supplierID) Methode einen Eingabeparameter akzeptiert, fordert der ObjectDataSource-Assistent uns zur 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 fest (die ID der in Schritt 2 erstellten FormView).

Geben Sie an, dass der Parameter

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

Nach Abschluss des ObjectDataSource-Assistenten enthält die GridView ein BoundField- oder CheckBoxField-Element für jedes der Datenfelder des Produkts. Lassen Sie uns das kürzen, um nur die ProductName- und UnitPrice-BoundFields zusammen mit dem Discontinued-CheckBoxField anzuzeigen. Darüber hinaus formatieren wir das UnitPrice-BoundField so, dass der 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 Lernprogramm einen Master/Details-Bericht an, der es dem Benutzer ermöglicht, einen Lieferanten aus der FormView oben zu wählen und die produkte anzuzeigen, die dieser Lieferant über das GridView unten bereitgestellt hat. Abbildung 11 zeigt einen Screenshot dieser Seite, wenn Sie den Lieferanten von Tokyo Traders aus der FormView auswählen.

Die Produkte des ausgewählten Lieferanten werden in der GridView angezeigt.

Abbildung 11: Die Produkte des ausgewählten Lieferanten werden in der 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, wenn sie geklickt wird, alle Produkte des Lieferanten abbricht, müssen wir zuerst eine Methode sowohl dem DAL als auch der BLL hinzufügen, die diese Aktion ausführt. Insbesondere wird diese Methode benannt DiscontinueAllProductsForSupplier(supplierID). Wenn auf die Schaltfläche von FormView geklickt wird, rufen wir diese Methode in der Geschäftslogikebene auf, indem wir den ausgewählten Lieferanten übergeben. Die BLL ruft dann die entsprechende Data Access Layer-Methode auf, die eine SupplierID Anweisung an die Datenbank ausgibt, die die Produkte des angegebenen Lieferanten UPDATEausschließt.

Wie wir in unseren vorherigen Lernprogrammen getan haben, verwenden wir einen Bottom-up-Ansatz, beginnend mit dem Erstellen der DAL-Methode, der BLL-Methode und schließlich der Implementierung der Funktionalität auf der ASP.NET Seite. Öffnen Sie das Northwind.xsd Typed DataSet im App_Code/DAL Ordner und fügen Sie eine neue Methode zu ProductsTableAdapter hinzu (klicken Sie mit der rechten Maustaste auf ProductsTableAdapter und wählen Sie "Abfrage hinzufügen" aus). Dadurch wird der Assistent für die TableAdapter-Abfragekonfiguration angezeigt, der uns durch den Prozess des Hinzufügens der neuen Methode führt. Beginnen Sie, indem Sie angeben, dass unsere 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, um das Bild in voller Größe anzuzeigen)

Als Nächstes fragt der Assistent uns, welche Art von Abfrage wir erstellen möchten. Da die DiscontinueAllProductsForSupplier(supplierID) Methode die Products Datenbanktabelle aktualisieren muss, müssen wir eine Abfrage erstellen, die Daten aktualisiert, indem sie das Discontinued Feld auf 1 für alle produkte festlegen, die von der angegebenen Tabelle supplierIDbereitgestellt werden.

Auswählen des UPDATE-Abfragetyps

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

Der nächste Assistentbildschirm enthält die vorhandene UPDATE Anweisung von TableAdapter, die jedes der felder aktualisiert, die in der Products DataTable definiert sind. 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, fordert der letzte Assistentbildschirm die Verwendung DiscontinueAllProductsForSupplierdes Namens der neuen Methode an. Schließen Sie den Assistenten ab, indem Sie auf die Schaltfläche "Fertig stellen" klicken. Wenn Sie zum DataSet-Designer zurückkehren, sollte im ProductsTableAdapter eine neue Methode mit dem Namen DiscontinueAllProductsForSupplier(@SupplierID) angezeigt werden.

Bennene die neue DAL-Methode

Abbildung 14: Benennen der neuen DAL-Methode DiscontinueAllProductsForSupplier (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

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

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

Diese Methode ruft einfach die DiscontinueAllProductsForSupplier(supplierID) Methode im DAL auf und übergibt den bereitgestellten supplierID Parameterwert. Wenn es Geschäftsregeln gab, die es nur erlaubten, die Produkte eines Lieferanten unter bestimmten Umständen einzustellen, 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 des Assistenten zum Konfigurieren der Datenquelle von ObjectDataSource auf der Registerkarte UPDATE aus. Ich habe dieses Attribut weggelassen, da wir die DiscontinueAllProductsForSupplier(supplierID) Methode direkt von einem Ereignishandler auf unserer ASP.NET-Seite aufrufen.

Schritt 5: Hinzufügen einer Schaltfläche "Alle Produkte beenden" zur FormView

Nachdem die DiscontinueAllProductsForSupplier(supplierID)-Methode in der BLL und DAL abgeschlossen ist, besteht der letzte Schritt, um die Möglichkeit hinzuzufügen, alle Produkte des ausgewählten Lieferanten einzustellen, darin, dem ItemTemplate des FormView-Steuerelements ein Button-Web-Steuerelement hinzuzufügen. Fügen wir eine solche Schaltfläche unter der Telefonnummer des Lieferanten mit dem Schaltflächentext hinzu, "Alle Produkte beenden" und einen ID Eigenschaftswert von DiscontinueAllProductsForSupplier. Sie können dieses Schaltflächenwebsteuerelement über den Designer hinzufügen, indem Sie im Smarttag von 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 ItemTemplate für die Schaltfläche "Alle Produkte beenden" zum FormView-Steuerelement (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 ausgelöst, und das Ereignis des FormView 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 ausgelöst wird, wenn auf ein Button-, LinkButton- oder ImageButton-Websteuerelement innerhalb der FormView geklickt wird. Das bedeutet, dass das Ereignis ausgelöst wird, ItemCommand wenn der Benutzer in der FormView von einer Seite zu einer anderen wechselt. Dasselbe gilt, wenn der Benutzer in einer Formularansicht 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 festzustellen, ob auf die Schaltfläche "Alle Produkte beenden" geklickt wurde oder ob es sich um eine andere Schaltfläche handelte. Dazu können wir die Eigenschaft des Button-Websteuerelements CommandName auf einen bestimmten Identifikationswert festlegen. Wenn die Schaltfläche angeklickt wird, wird dieser CommandName-Wert an den ItemCommand-Ereignishandler übergeben, um festzustellen, ob auf die Schaltfläche "Alle Produkte einstellen" geklickt wurde. Legen Sie die Eigenschaft der Schaltfläche "Alle Produkte beenden" CommandName auf "DiscontinueProducts" fest.

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

Nachdem Sie diese Änderungen vorgenommen haben, 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. In diesem Fall möchten wir eine Instanz der ProductsBLL Klasse erstellen und ihre DiscontinueAllProductsForSupplier(supplierID) Methode aufrufen, wobei wir die SupplierID des ausgewählten FormView übergeben.

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 über die EigenschaftSupplierIDauf den SelectedValue aktuellen ausgewählten Lieferanten in formView zugegriffen 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 automatisch von Visual Studio festgelegt, wenn die ObjectDataSource wieder in Schritt 2 an die FormView gebunden SupplierID wird.

Nehmen Sie sich mit dem ItemCommand erstellten Ereignishandler einen Moment Zeit, um die Seite zu testen. Navigieren Sie zum Supplier "Cooperativa de Quesos "Las Cabras" (es ist der fünfte Lieferant in der FormView für mich). Dieser Lieferant bietet zwei Produkte, Queso Cabrales und Queso Manchego La Pastora, die beide nicht mehr eingestellt sind.

Stellen Sie sich vor, dass die Cooperativa de Quesos 'Las Cabras' aus dem Geschäft gegangen ist und daher ihre Produkte eingestellt werden sollen. 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 Bild in voller Größe anzuzeigen)

Wenn Sie im clientseitigen Bestätigungsdialogfeld auf "OK" klicken, wird die Formularübermittlung fortgesetzt, wodurch ein Postback ausgelöst wird, bei dem das ItemCommand-Ereignis des FormView ausgelöst wird. Der von uns erstellte Ereignishandler wird dann ausgeführt und ruft die DiscontinueAllProductsForSupplier(supplierID) Methode auf und beendet sowohl die Produkte Queso Cabrales als auch Queso Manchego La Pastora.

Wenn Sie den Ansichtszustand von GridView deaktiviert haben, wird GridView bei jedem Postback an den zugrunde liegenden Datenspeicher zurückgebunden und wird daher sofort aktualisiert, um anzuzeigen, dass diese beiden Produkte jetzt nicht mehr verfügbar sind (siehe Abbildung 17). Wenn Sie den Ansichtszustand in GridView jedoch nicht deaktiviert haben, müssen Sie die Daten nach dieser Änderung manuell erneut an gridView binden. Führen Sie dazu einfach einen Aufruf der GridView-Methode DataBind() unmittelbar nach dem Aufrufen der DiscontinueAllProductsForSupplier(supplierID) Methode durch.

Nachdem Sie auf die Schaltfläche

Abbildung 17: Nachdem Sie auf die Schaltfläche "Alle Produkte einstellen" geklickt haben, werden die Produkte des Lieferanten entsprechend aktualisiert (Klicken Sie hier, um das Bild mit voller Größe anzuzeigen)

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

Wie bei der Schaltfläche "Alle Produkte beenden" in formView müssen wir zuerst die entsprechenden Methoden "Data Access Layer" und "Business Logic Layer" hinzufügen, um Schaltflächen zum Erhöhen und Verringern des Preises für ein Produkt in der GridView hinzuzufügen. Da wir bereits über eine Methode verfügen, die eine einzelne Produktzeile im DAL aktualisiert, können wir diese Funktionalität bereitstellen, indem wir eine neue Überladung für die Methode in der UpdateProduct BLL erstellen.

Unsere bisherigen UpdateProduct Überladungen haben eine Kombination aus Produktfeldern als skalare Eingabewerte übernommen und dann nur diese Felder für das angegebene Produkt aktualisiert. Für diese Überladung weichen wir geringfügig vom Standard ab und übergeben stattdessen das ProductID des Produkts und den Prozentsatz, um den das UnitPrice angepasst werden soll (anstatt das neue, angepasste UnitPrice selbst zu übergeben). Mit diesem Ansatz wird der Code vereinfacht, den wir in der ASP.NET Code-Behind-Seitenklasse schreiben müssen, da wir uns nicht mit der Ermittlung der aktuellen ProdukteUnitPrice beschäftigen müssen.

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

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 verwendet die DAL-Methode GetProductByProductID(productID), um Informationen zum angegebenen Produkt abzurufen. 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 keinNULLUnitPrice Wert vorhanden ist, aktualisiert die Methode die Produkte UnitPrice um den angegebenen Prozentsatz (unitPriceAdjustmentPercent).

Schritt 7: Hinzufügen der Schaltflächen "Vergrößern" und "Verkleinern" zur GridView

GridView (und DetailsView) bestehen aus einer Sammlung von Feldern. Zusätzlich zu BoundFields, CheckBoxFields und TemplateFields enthält ASP.NET das ButtonField, das wie der Name impliziert, als Spalte mit einem Button-, LinkButton- oder ImageButton-Element für jede Zeile gerendert wird. Ähnlich wie bei der FormView bewirkt das Klicken auf eine beliebige Schaltfläche, ob in den Pagingschaltflächen, Bearbeiten- oder Löschen-Schaltflächen, Sortierschaltflächen usw., einen Postback und löst das RowCommand-Ereignis des GridView aus.

Das ButtonField verfügt über eine CommandName Eigenschaft, die jedem der Schaltflächeneigenschaften 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 Preis +10% und dem anderen mit dem Text "Preis -10%". Wenn Sie diese ButtonFields hinzufügen möchten, klicken Sie im Smarttag von GridView auf den Link "Spalten bearbeiten", wählen Sie den Feldtyp "ButtonField" aus 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 Schaltflächenfelder auf Preis +10% und Preis -10% und die CommandName Eigenschaften auf „IncreasePrice“ bzw. „DecreasePrice“ fest. Standardmäßig rendert ein ButtonField seine Spalte mit Schaltflächen als LinkButtons. Dies kann jedoch über die ButtonType Eigenschaft von ButtonField geändert werden. Lassen Sie diese beiden ButtonFields als normale Schaltflächen rendern. Legen Sie daher die ButtonType-Eigenschaft auf Button. Abbildung 19 zeigt das Dialogfeld "Felder", nachdem diese Änderungen vorgenommen wurden; Nachfolgend sehen Sie das deklarative Markup von GridView.

Konfigurieren der Eigenschaften ButtonFields Text, CommandName und ButtonType

Abbildung 19: Konfigurieren der ButtonFields Text- CommandNameund ButtonType Eigenschaften

<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äche "Preis +10 %" oder "Preis -10 %" geklickt wurde, muss die Zeile ProductID bestimmt werden, auf deren Schaltfläche geklickt wurde. Danach soll die Methode UpdateProduct der Klasse ProductsBLL aufgerufen werden, wobei die entsprechende prozentuale Anpassung UnitPrice zusammen mit dem ProductID übergeben wird. Der folgende Code führt die folgenden 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 die ProductID Zeile zu ermitteln, auf deren Schaltfläche "Preis +10% oder Preis -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 DataKeyNames-Eigenschaft von GridView beim Binden der ObjectDataSource an GridView in Visual Studio auf "ProductID" festgelegt wurde, stellt DataKeys(rowIndex).Value den angegebenen rowIndex für ProductID bereit.

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

Ähnlich wie bei der Schaltfläche "Alle Produkte beenden", wird, falls Sie den Ansichtszustand von GridView deaktiviert haben, das GridView bei jedem Postback an den zugrunde liegenden Datenspeicher zurückgebunden. Somit wird es sofort aktualisiert, um eine Preisänderung anzuzeigen, die durch einen Klick auf eine der Schaltflächen entsteht. Wenn Sie den Ansichtszustand in GridView jedoch nicht deaktiviert haben, müssen Sie die Daten nach dieser Änderung manuell erneut an gridView binden. Führen Sie dazu einfach einen Aufruf der GridView-Methode DataBind() unmittelbar nach dem Aufrufen der UpdateProduct Methode durch.

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

Die GridView umfasst Preis +10% und Preis -10% Schaltflächen

Abbildung 20: Die GridView umfasst Preis +10 % und Preis -10 % Schaltflächen (Klicken Sie, 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, um das Bild mit voller Größe anzuzeigen)

Hinweis

In den GridView- und DetailsView-Steuerelementen können auch Schaltflächen, Link-Schaltflächen oder Bild-Schaltflächen in ihre TemplateFields eingefügt werden. Wie beim BoundField auslösen diese Schaltflächen, wenn darauf geklickt wird, einen Postback, wodurch das GridView-Ereignis RowCommand ausgelöst wird. Beim Hinzufügen von Buttons in einem TemplateField wird der Button jedoch nicht automatisch auf den Index der Zeile festgelegt, wie es bei der Verwendung von ButtonFields der Fall ist.CommandArgument Wenn Sie tatsächlich den Zeilenindex der Schaltfläche bestimmen müssen, auf die innerhalb des RowCommand Ereignishandlers geklickt wurde, müssen Sie die Eigenschaft der Schaltfläche CommandArgument manuell in der deklarativen Syntax innerhalb des TemplateFields festlegen, indem Sie einen Code wie den folgenden verwenden:
<asp:Button runat="server" ... CommandArgument='<%# ((GridViewRow) Container).RowIndex %>'.

Zusammenfassung

Die GridView-, DetailsView- und FormView-Steuerelemente können alle Schaltflächen, LinkButtons oder ImageButtons enthalten. Solche Schaltflächen verursachen beim Klicken einen Postback und lösen das ItemCommand Ereignis in den Steuerelementen "FormView" und "DetailsView" und das RowCommand Ereignis in "GridView" aus. Diese Datenwebsteuerelemente verfügen über integrierte Funktionen zum Behandeln allgemeiner befehlsbezogener Aktionen, z. B. Löschen oder Bearbeiten von Datensätzen. Wir können jedoch auch Schaltflächen verwenden, die beim Klicken mit der Ausführung unseres eigenen benutzerdefinierten Codes antworten.

Dazu müssen wir einen Ereignishandler für das ItemCommand-Ereignis oder das RowCommand-Ereignis erstellen. In diesem Ereignishandler überprüfen wir zuerst den eingehenden CommandName-Wert, um zu bestimmen, auf welche Schaltfläche geklickt wurde, und ergreifen dann die entsprechende benutzerdefinierte Aktion. In diesem Lernprogramm haben wir erfahren, wie Sie mit Schaltflächen und ButtonFields alle Produkte für einen bestimmten Lieferanten einstellen oder den Preis eines bestimmten Produkts um 10 % erhöhen oder verringern.

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.