Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
von Scott Mitchell
In diesem Lernprogramm 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 schreibgeschützten Zugriff auf die Berichtsdaten erfordern, ist es nicht ungewöhnlich, dass Berichte die Möglichkeit haben, 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. Zusätzlich listet ein GridView die vom ausgewählten Lieferanten bereitgestellten Produkte auf, wobei jede Zeile die Buttons "Preiserhöhung" und "Preisnachlass" enthält, die, wenn geklickt, den Preis des Produkts um 10 % erhöhen oder reduzieren (siehe Abbildung 1).
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.aspxCustomButtons.aspx
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 Entwurfsansicht der Seite ziehen.
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.
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
Lassen Sie uns mit diesem Lernprogramm beginnen, indem Sie 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 eine Schaltfläche, die, wenn sie geklickt wird, alle Produkte des Lieferanten als eingestellt markiert. Bevor wir uns mit dem Hinzufügen der benutzerdefinierten Schaltfläche zur FormView befassen, lassen Sie uns zuerst die FormView erstellen, damit 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 Smarttag von FormView die Option, eine neue ObjectDataSource namens SuppliersDataSource zu erstellen.
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 von der 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.
Abbildung 6: Konfigurieren der Datenquelle für die Verwendung der SuppliersBLL Klassenmethode GetSuppliers() (Klicken, um das Bild in voller Größe anzuzeigen)
Nach dem Konfigurieren der ObjectDataSource generiert Visual Studio ein InsertItemTemplate, EditItemTemplateund ItemTemplate für die FormView. Entfernen Sie InsertItemTemplate und EditItemTemplate und ändern Sie 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.
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 einstellen" zur Vorlage "FormView" 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 eine GridView hinzu, legen Sie dessen ID-Eigenschaft auf SuppliersProducts fest, und fügen Sie eine neue ObjectDataSource namens SuppliersProductsDataSource hinzu.
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 ProductsBLL-Klassenmethode GetProductsBySupplierID(supplierID) verwendet wird (siehe Abbildung 9). Obwohl dieses GridView 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 für die Registerkarten UPDATE, INSERT und DELETE von ObjectDataSource auf (Keine) festlegen.
Abbildung 9: Konfigurieren der Datenquelle für die Verwendung der ProductsBLL Klasse GetProductsBySupplierID(supplierID) -Methode (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).
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 für jedes Datenfeld des Produkts ein BoundField- oder CheckBoxField-Element. Lassen Sie uns dies kürzen, um nur die ProductName und UnitPrice BoundFields zusammen mit dem Discontinued CheckBoxField anzuzeigen. Darüber hinaus lassen Sie uns das UnitPrice BoundField so formatieren, dass der Text als Währung formatiert ist. Ihr deklaratives Markup von GridView und SuppliersProductsDataSource ObjectDataSource 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.
Abbildung 11: Die Produkte des ausgewählten Lieferanten werden in der GridView angezeigt (Zum Anzeigen des Bilds mit voller Größe klicken)
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 FormView-Schaltfläche geklickt wird, rufen wir diese Methode in der Geschäftslogikebene auf, und übergeben die ausgewählten Lieferanten; 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 UPDATEanbricht.
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.
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.
Abbildung 13: Auswählen des UPDATE-Abfragetyps (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Der nächste Assistent-Bildschirm enthält die vorhandene UPDATE TableAdapter-Anweisung, 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 Assistentenbildschirm die Verwendung DiscontinueAllProductsForSupplierdes neuen Methodennamens 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.
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 Function DiscontinueAllProductsForSupplier(supplierID As Integer) As Integer
Return Adapter.DiscontinueAllProductsForSupplier(supplierID)
End Function
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 Methoden in der DiscontinueAllProductsForSupplier(supplierID) BLL und DAL abgeschlossen sind, besteht der letzte Schritt, um die Möglichkeit hinzuzufügen, alle Produkte eines ausgewählten Lieferanten einzustellen, darin, ein Button-Web-Steuerelement in die FormView ItemTemplate einzufügen. Lassen Sie uns einen solchen Button unterhalb der Telefonnummer des Lieferanten hinzufügen, mit dem Text "Alle Produkte einstellen" und einem ID Eigenschaftswert von DiscontinueAllProductsForSupplier. Sie können dieses Schaltflächen-Websteuerelement ü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.
Abbildung 15: Hinzufügen eines Websteuerelements für die Schaltfläche "Alle Produkte beenden" zu FormViews ItemTemplate (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Wenn auf die Schaltfläche ein Benutzer klickt, der die Seite besucht, wird ein Postback ausgelöst, und das FormView-Ereignis ItemCommand 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 "Alle Produkte beenden" CommandName auf "DiscontinueProducts" fest.
Lassen Sie uns schließlich ein clientseitiges Bestätigungsdialogfeld verwenden, 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 OnClientClick-Eigenschaft des Button-Websteuerelements auf return confirm('This will mark _all_ of this supplier\'s products as discontinued. Are you certain you want to do this?');
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 Sub Suppliers_ItemCommand(sender As Object, e As FormViewCommandEventArgs) _
Handles Suppliers.ItemCommand
If e.CommandName.CompareTo("DiscontinueProducts") = 0 Then
' The "Discontinue All Products" Button was clicked.
' Invoke the ProductsBLL.DiscontinueAllProductsForSupplier(supplierID) method
' First, get the SupplierID selected in the FormView
Dim supplierID As Integer = CType(Suppliers.SelectedValue, Integer)
' Next, create an instance of the ProductsBLL class
Dim productInfo As New ProductsBLL()
' Finally, invoke the DiscontinueAllProductsForSupplier(supplierID) method
productInfo.DiscontinueAllProductsForSupplier(supplierID)
End If
End Sub
Beachten Sie, dass über die FormView-Eigenschaft SupplierIDauf 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 s-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 Lieferanten der 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).
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, in dem das FormView-Ereignis ItemCommand 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 an den zugrunde liegenden Datenspeicher für jeden Postback zurückgebunden und wird daher sofort aktualisiert, um anzuzeigen, dass diese beiden Produkte jetzt nicht mehr vorhanden 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. Um dies zu erreichen, rufen Sie einfach die GridView-Methode DataBind() unmittelbar nach dem Aufrufen der DiscontinueAllProductsForSupplier(supplierID) Methode auf.
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 in voller Größe anzuzeigen)
Schritt 6: Erstellen einer UpdateProduct-Überladung in der Geschäftslogikebene zur Anpassung 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 von diesem Standard ab und übergeben stattdessen das Produkt ProductID und den Prozentsatz, um den UnitPrice angepasst werden soll (im Gegensatz zur Übergabe des neuen, angepassten UnitPrice selbst). Mit diesem Ansatz wird der Code vereinfacht, den wir in der ASP.NET-Seiten-Code-Behind-Klasse schreiben müssen, da wir uns nicht mit der Ermittlung des aktuellen Produkts UnitPrice befassen müssen.
Die UpdateProduct Überladung für dieses Tutorial ist unten gezeigt:
Public Function UpdateProduct _
(unitPriceAdjustmentPercentage As Decimal, productID As Integer) As Boolean
Dim products As Northwind.ProductsDataTable = Adapter.GetProductByProductID(productID)
If products.Count = 0 Then
' no matching record found, return false
Return False
End If
Dim product As Northwind.ProductsRow = products(0)
' Adjust the UnitPrice by the specified percentage (if it's not NULL)
If Not product.IsUnitPriceNull() Then
product.UnitPrice *= unitPriceAdjustmentPercentage
End If
' Update the product record
Dim rowsAffected As Integer = Adapter.Update(product)
' Return true if precisely one row was updated, otherwise false
Return rowsAffected = 1
End Function
Diese Überladung ruft Informationen zum angegebenen Produkt über die DAL-Methode GetProductByProductID(productID) ab. 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-NULLUnitPrice Wert vorhanden ist, aktualisiert die Methode das Produkt UnitPrice um den angegebenen Prozentwert (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 der Schaltflächen innerhalb der GridView-Paging-Buttons, "Bearbeiten" oder "Löschen", der Sortierschaltflächen usw. einen Postback und löst das GridView-Ereignis RowCommand 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.
Lassen Sie uns zwei neue ButtonFields zu GridView hinzufügen, 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 auf den Link "Spalten bearbeiten" im Smarttag "GridView", wählen Sie den Feldtyp "ButtonField" aus der Liste oben links aus, und klicken Sie auf die Schaltfläche "Hinzufügen".
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 ButtonField-Eigenschaft ButtonTypegeändert werden. Lassen Sie uns diese beiden Button-Felder als normale Schaltflächen gerendert werden; legen Sie daher die ButtonType-Eigenschaft auf Button. Abbildung 19 zeigt das Dialogfeld "Felder", nachdem diese Änderungen vorgenommen wurden; Nachfolgend sehen Sie das deklarative GridView-Markup.
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 s-Ereignis RowCommand zu erstellen. Wenn dieser Ereignishandler ausgelöst wird, weil entweder auf die Schaltflächen "Preis +10 %" oder "Preis -10 %" geklickt wurde, muss die Zeile ProductID bestimmt werden, auf deren Schaltfläche geklickt wurde, und dann die Methode der Klasse ProductsBLLUpdateProduct aufrufen, wobei die entsprechende prozentuale Anpassung zusammen mit der ProductID. Der folgende Code führt die folgenden Aufgaben aus:
Protected Sub SuppliersProducts_RowCommand _
(sender As Object, e As GridViewCommandEventArgs) _
Handles SuppliersProducts.RowCommand
If e.CommandName.CompareTo("IncreasePrice") = 0 OrElse _
e.CommandName.CompareTo("DecreasePrice") = 0 Then
' The Increase Price or Decrease Price Button has been clicked
' Determine the ID of the product whose price was adjusted
Dim productID As Integer = Convert.ToInt32( _
SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value)
' Determine how much to adjust the price
Dim percentageAdjust As Decimal
If e.CommandName.CompareTo("IncreasePrice") = 0 Then
percentageAdjust = 1.1
Else
percentageAdjust = 0.9
End If
' Adjust the price
Dim productInfo As New ProductsBLL()
productInfo.UpdateProduct(percentageAdjust, productID)
End If
End Sub
Um die ProductID Zeile zu ermitteln, auf deren Schaltfläche "Preis +10% oder Preis -10 %" geklickt wurde, müssen wir die GridView-Sammlung DataKeys konsultieren. Diese Auflistung enthält die Werte der felder, die in der DataKeyNames Eigenschaft für jede GridView-Zeile angegeben sind. Da die Eigenschaft von GridView DataKeyNames beim Binden der ObjectDataSource an GridView von Visual Studio auf "ProductID" festgelegt wurde, liefert DataKeys(rowIndex).Value den ProductID für den angegebenen rowIndex.
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, wenn Sie den ViewState von GridView deaktiviert haben, GridView bei jedem Postback an den zugrunde liegenden Datenspeicher zurückgebunden und daher sofort aktualisiert, um unmittelbar eine Preisänderung widerzuspiegeln, die bei einem Klick auf eine der Schaltflächen eintritt. Wenn Sie den Ansichtszustand in GridView jedoch nicht deaktiviert haben, müssen Sie die Daten nach dieser Änderung manuell erneut an gridView binden. Um dies zu erreichen, rufen Sie einfach die GridView-Methode DataBind() unmittelbar nach dem Aufrufen der UpdateProduct Methode auf.
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.
Abbildung 20: Die GridView umfasst Preis +10 % und Preis -10 % Schaltflächen (Klicken Sie, um das Bild in voller Größe anzuzeigen)
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 bei "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 CommandArgument jedoch nicht automatisch auf den Index der Zeile festgelegt, wie es bei der Verwendung von ButtonFields der Fall ist. Wenn Sie 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 innerhalb des TemplateFields in der deklarativen Syntax festlegen, indem Sie einen Code wie:
<asp:Button runat="server" ... CommandArgument='<%# CType(Container, GridViewRow).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.