Hinzufügen von Schaltflächen zu einem GridView-Steuerelement und Zuweisen von Funktionen für diese Schaltflächen (C#)
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, bei dem jeder Datensatz im Bericht angezeigt wird, der, wenn darauf geklickt wird, einen Postback verursacht und einen 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 eingestellt 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).
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 Webseiten des Lernprogramms 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
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 Default.aspx
hinzu, indem Sie es aus der 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 Lernprogramme-Website über einen 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
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 nur das FormularAnsicht, 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 Suppliers
festlegen. Wählen Sie im Smarttag von FormView eine neue 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 abfragen aus der Methode der SuppliersBLL
Klasse GetSuppliers()
(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 Klassesmethode (Zum Anzeigen des SuppliersBLL
Bilds GetSuppliers()
mit voller Größe klicken)
Nach dem Konfigurieren der ObjectDataSource generiert Visual Studio ein InsertItemTemplate
, EditItemTemplate
und ItemTemplate
für die FormView. Entfernen Sie den InsertItemTemplate
Namen EditItemTemplate
und die Telefonnummer des Lieferanten, und ändern ItemTemplate
Sie sie so, dass sie nur den Firmennamen und die Telefonnummer des Lieferanten anzeigt. Aktivieren Sie schließlich die Pagingunterstützung für die FormView, indem Sie das Kontrollkästchen "Paging aktivieren" über das Smarttag 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 Felder und Phone
Felder CompanyName
aus dem aktuell ausgewählten Lieferanten auf (Klicken, 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 fest SuppliersProducts
, und fügen Sie eine neue ObjectDataSource mit dem Namen hinzu 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 ProductsBLL-Klasse die Methode der ProductsBLL-Klasse GetProductsBySupplierID(supplierID)
verwendet (siehe Abbildung 9). Obwohl dieses GridView-Steuerelement die Anpassung des Preises eines Produkts zulässt, verwendet es nicht die integrierten Bearbeitungs- oder Löschfunktionen aus gridView. Daher können wir die Dropdownliste auf (Keine) für die Registerkarten UPDATE, INSERT und DELETE von ObjectDataSource festlegen.
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" fest ( Suppliers
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 ein BoundField- oder CheckBoxField-Element für die einzelnen Datenfelder des Produkts. Lassen Sie uns dies kürzen, um nur die und UnitPrice
BoundFields ProductName
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.
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 UPDATE
Anweisung an die Datenbank ausgibt, die die Produkte des angegebenen Lieferanten SupplierID
ausschließ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 dem Ordner 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 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 fordert der Assistent uns auf, welche Art von Abfrage erstellt werden soll. 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 supplierID
bereitgestellt werden.
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 DiscontinueAllProductsForSupplier
des 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 eine neue Methode im ProductsTableAdapter
Benannten angezeigt DiscontinueAllProductsForSupplier(@SupplierID)
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äftslogikebene 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 zum Hinzufügen der Möglichkeit, alle Produkte für den ausgewählten Lieferanten einzustellen, darin, dem FormView-Steuerelement ItemTemplate
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.
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 auf die Schaltfläche ein Benutzer klickt, der die Seite besucht, wird ein Postback ausgelöst, und das Ereignis von ItemCommand
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 auf die Schaltfläche geklickt wird, wird dieser CommandName
Wert an den ItemCommand
Ereignishandler übergeben, sodass wir bestimmen können, ob auf die Schaltfläche "Alle Produkte einstellen" geklickt wurde. Legen Sie die Eigenschaft "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 beim Hinzufügen von clientseitiger Bestätigung beim Löschen des Lernprogramms 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 die zugehörige DiscontinueAllProductsForSupplier(supplierID)
Methode aufrufen und die SupplierID
ausgewählte 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 Eigenschaft von FormViewSelectedValue
auf den SupplierID
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).
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 Ereignis von FormView 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 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.
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 unterscheiden wir uns geringfügig von diesem Standard und übergeben stattdessen die ProductID
Produkte und den Prozentsatz, um den sie anpassen UnitPrice
soll (im Gegensatz zur Übergabe des neuen, angepassten UnitPrice
selbst). Mit diesem Ansatz wird der Code vereinfacht, den wir in der ASP.NET SeitencodeBehind-Klasse schreiben müssen, da wir nicht mit der Ermittlung der aktuellen Produkte UnitPrice
zu stören müssen.
Die UpdateProduct
Überladung für dieses Lernprogramm wird 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 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 keinNULL
UnitPrice
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 die FormView bewirkt das Klicken auf eine beliebige Schaltfläche in den GridView-Pagingschaltflächen, "Bearbeiten" oder "Löschen", 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.
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".
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 "IncreasePrice" bzw. "DecreasePrice" fest. Standardmäßig rendert ein ButtonField seine Spalte mit Schaltflächen als LinkButtons. Dies kann jedoch über die Eigenschaft von ButtonField ButtonType
geändert werden. Lassen Sie uns diese beiden ButtonFields als normale Schaltflächen gerendert haben. 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.
Abbildung 19: Konfigurieren der ButtonFields Text
- CommandName
und 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, da entweder auf die Schaltflächen "Preis +10 %" oder "Preis -10 %" geklickt wurde, muss die ProductID
Zeile bestimmt werden, auf deren Schaltfläche geklickt wurde, und dann die Methode der ProductsBLL
Klasse UpdateProduct
aufrufen und dann die entsprechende UnitPrice
Prozentuale Anpassung zusammen mit der .ProductID
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 Eigenschaft von GridView DataKeyNames
beim Binden der ObjectDataSource an das GridView-Objekt auf "ProductID" von Visual Studio festgelegt wurde, DataKeys(rowIndex).Value
stellt sie für ProductID
den angegebenen rowIndex bereit.
Das ButtonField übergibt automatisch den rowIndex der Zeile, auf deren Schaltfläche durch den e.CommandArgument
Parameter geklickt wurde. Um die ProductID
Zeile zu ermitteln, auf deren Schaltfläche "Preis +10% oder Preis -10 %" geklickt wurde, verwenden wir Folgendes. Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value)
Wie bei der Schaltfläche "Alle Produkte beenden", wenn Sie den Ansichtszustand von GridView deaktiviert haben, wird GridView auf jeden Postback an den zugrunde liegenden Datenspeicher zurückgebunden und daher sofort aktualisiert, um eine Preisänderung widerzuspiegeln, die durch Klicken auf eine der Schaltflächen erfolgt. 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 Anzeigen der von Grandma Kelly es Homestead bereitgestellten Produkte. Abbildung 21 zeigt die Ergebnisse, nachdem die Schaltfläche "Preis +10%" zweimal für Die Boysenberry Spread von Grandma und die Schaltfläche "Preis -10%" 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
GridView (und DetailsView) können auch Schaltflächen, LinkButtons oder ImageButtons zu ihren TemplateFields hinzugefü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 Schaltflächen in einem TemplateField wird die Schaltfläche jedoch nicht automatisch auf den Index der Zeile festgelegt, wie dies CommandArgument
bei der Verwendung von ButtonFields der Vorgang 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 in der deklarativen Syntax innerhalb des TemplateFields mithilfe von Code wie:
<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 " RowCommand
Event" 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 Ereignis oder RowCommand
das ItemCommand
Ereignis erstellen. In diesem Ereignishandler überprüfen wir zuerst den eingehenden CommandName
Wert, um zu bestimmen, auf welche Schaltfläche geklickt wurde, und ergreifen Sie 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 über mitchell@4GuysFromRolla.com seinen Blog erreicht werden, der unter .http://ScottOnWriting.NET