Eine Übersicht über das Einfügen, Aktualisieren und Löschen von Daten (C#)
von Scott Mitchell
In diesem Lernprogramm erfahren Sie, wie Sie die Methoden Insert(), Update() und Delete() einer ObjectDataSource den Methoden von BLL-Klassen zuordnen und wie Sie die GridView-, DetailsView- und FormView-Steuerelemente konfigurieren, um Datenänderungsfunktionen bereitzustellen.
Einführung
In den vergangenen Lernprogrammen haben wir untersucht, wie Daten mithilfe der Steuerelemente GridView, DetailsView und FormView auf einer ASP.NET Seite angezeigt werden. Diese Steuerelemente funktionieren einfach mit ihnen bereitgestellten Daten. In der Regel steuert diese Zugriffsdaten mithilfe eines Datenquellensteuerelements, z. B. objectDataSource. Wir haben gesehen, wie die ObjectDataSource als Proxy zwischen der ASP.NET Seite und den zugrunde liegenden Daten fungiert. Wenn eine GridView Daten anzeigen muss, ruft sie die Methode der ObjectDataSource Select()
auf, die wiederum eine Methode aus unserer Business Logic Layer (BLL) aufruft, die eine Methode im entsprechenden Data Access Layer (DAL) TableAdapter aufruft, was wiederum eine SELECT
Abfrage an die Northwind-Datenbank sendet.
Denken Sie daran, dass Visual Studio beim Erstellen der TableAdapters im DAL in unserem ersten Lernprogramm automatisch Methoden zum Einfügen, Aktualisieren und Löschen von Daten aus der zugrunde liegenden Datenbanktabelle hinzugefügt hat. Darüber hinaus haben wir beim Erstellen einer Geschäftslogikebene Methoden in der BLL entwickelt, die in diese Datenänderung DAL-Methoden aufgerufen haben.
Zusätzlich zu seiner Select()
Methode verfügt objectDataSource auch über Insert()
, Update()
und Delete()
Methoden. Wie die Select()
Methode können diese drei Methoden Methoden methoden in einem zugrunde liegenden Objekt zugeordnet werden. Wenn sie zum Einfügen, Aktualisieren oder Löschen von Daten konfiguriert sind, bieten die Steuerelemente GridView, DetailsView und FormView eine Benutzeroberfläche zum Ändern der zugrunde liegenden Daten. Diese Benutzeroberfläche ruft die Insert()
Methoden Update()
und Methoden Delete()
der ObjectDataSource auf, die dann die zugeordneten Methoden des zugrunde liegenden Objekts aufrufen (siehe Abbildung 1).
Abbildung 1: Die Methoden "ObjectDataSourceInsert()
Update()
" und Delete()
"Methoden" dienen als Proxy in der BLL (Klicken, um das Bild in voller Größe anzuzeigen)
In diesem Lernprogramm erfahren Sie, wie Sie die ObjectDataSource-Steuerelemente Insert()
Update()
und Delete()
Methoden Methoden von Klassen in der BLL zuordnen und wie Sie die GridView-, DetailsView- und FormView-Steuerelemente konfigurieren, um Datenänderungsfunktionen bereitzustellen.
Schritt 1: Erstellen der Webseiten "Einfügen", "Aktualisieren" und "Löschen von Lernprogrammen"
Bevor wir mit dem Einfügen, Aktualisieren und Löschen von Daten beginnen, nehmen wir uns zunächst einen Moment Zeit, um die ASP.NET Seiten in unserem Websiteprojekt zu erstellen, die wir für dieses Lernprogramm und die nächsten benötigen. Beginnen Sie mit dem Hinzufügen eines neuen Ordners mit dem Namen EditInsertDelete
. Fügen Sie als Nächstes die folgenden ASP.NET Seiten zu diesem Ordner hinzu, und stellen Sie sicher, dass jede Seite der Site.master
Gestaltungsvorlage zugeordnet wird:
Default.aspx
Basics.aspx
DataModificationEvents.aspx
ErrorHandling.aspx
UIValidation.aspx
CustomizedUI.aspx
OptimisticConcurrency.aspx
ConfirmationOnDelete.aspx
UserLevelAccess.aspx
Abbildung 2: Hinzufügen der ASP.NET Seiten für die datenänderungsbezogenen Lernprogramme
Wie in den anderen Ordnern Default.aspx
werden im EditInsertDelete
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 angepassten Formatierung <siteMapNode>
hinzu:
<siteMapNode title="Editing, Inserting, and Deleting"
url="~/EditInsertDelete/Default.aspx"
description="Samples of Reports that Provide Editing, Inserting,
and Deleting Capabilities">
<siteMapNode url="~/EditInsertDelete/Basics.aspx"
title="Basics"
description="Examines the basics of data modification with the
GridView, DetailsView, and FormView controls." />
<siteMapNode url="~/EditInsertDelete/DataModificationEvents.aspx"
title="Data Modification Events"
description="Explores the events raised by the ObjectDataSource
pertinent to data modification." />
<siteMapNode url="~/EditInsertDelete/ErrorHandling.aspx"
title="Error Handling"
description="Learn how to gracefully handle exceptions raised
during the data modification workflow." />
<siteMapNode url="~/EditInsertDelete/UIValidation.aspx"
title="Adding Data Entry Validation"
description="Help prevent data entry errors by providing validation." />
<siteMapNode url="~/EditInsertDelete/CustomizedUI.aspx"
title="Customize the User Interface"
description="Customize the editing and inserting user interfaces." />
<siteMapNode url="~/EditInsertDelete/OptimisticConcurrency.aspx"
title="Optimistic Concurrency"
description="Learn how to help prevent simultaneous users from
overwritting one another s changes." />
<siteMapNode url="~/EditInsertDelete/ConfirmationOnDelete.aspx"
title="Confirm On Delete"
description="Prompt a user for confirmation when deleting a record." />
<siteMapNode url="~/EditInsertDelete/UserLevelAccess.aspx"
title="Limit Capabilities Based on User"
description="Learn how to limit the data modification functionality
based on the user role or permissions." />
</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 Einträge für das Bearbeiten, Einfügen und Löschen von Lernprogrammen.
Schritt 2: Hinzufügen und Konfigurieren des ObjectDataSource-Steuerelements
Da sich gridView, DetailsView und FormView in ihren Datenänderungsfunktionen und -layouts unterscheiden, untersuchen wir die einzelnen Elemente einzeln. Anstatt jedes Steuerelement mit einer eigenen ObjectDataSource zu verwenden, erstellen wir einfach eine einzelne ObjectDataSource, die alle drei Steuerelementbeispiele freigeben können.
Öffnen Sie die Basics.aspx
Seite, ziehen Sie eine ObjectDataSource aus der Toolbox in den Designer, und klicken Sie auf den Link "Datenquelle konfigurieren" aus dem Smarttag. Da es sich ProductsBLL
um die einzige BLL-Klasse handelt, die Bearbeitungs-, Einfüge- und Löschmethoden bereitstellt, konfigurieren Sie die ObjectDataSource so, dass diese Klasse verwendet wird.
Abbildung 5: Konfigurieren der ObjectDataSource für die Verwendung der ProductsBLL
Klasse (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Auf dem nächsten Bildschirm können wir angeben, welche Methoden der ProductsBLL
Klasse den ObjectDataSource-Dateien Update()
Select()
Insert()
zugeordnet sind, und Delete()
indem Sie die entsprechende Registerkarte auswählen und die Methode aus der Dropdownliste auswählen. Abbildung 6, die nun vertraut sein sollte, ordnet die Methode von Select()
ObjectDataSource der Methode der ProductsBLL
Klasse GetProducts()
zu. Die Insert()
Methoden Update()
und Delete()
Methoden können konfiguriert werden, indem sie die entsprechende Registerkarte in der Liste am oberen Rand auswählen.
Abbildung 6: Gibt die ObjectDataSource alle Produkte zurück (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Abbildung 7, 8 und 9 zeigen die Registerkarten UPDATE, INSERT und DELETE von ObjectDataSource an. Konfigurieren Sie diese Registerkarten so, dass die Insert()
Update()
Methoden ,, und Delete()
die Methoden der ProductsBLL
Klasse AddProduct
UpdateProduct
bzwDeleteProduct
. methoden aufgerufen werden.
Abbildung 7: Zuordnen der Methode von ObjectDataSource Update()
zur Methode der ProductBLL
Klasse UpdateProduct
(Klicken, um das Bild in voller Größe anzuzeigen)
Abbildung 8: Zuordnen der Methode von ObjectDataSource Insert()
zur Add-Methode Product
der ProductBLL
Klasse (Klicken, um das Bild in voller Größe anzuzeigen)
Abbildung 9: Zuordnen der Methode von ObjectDataSource Delete()
zur Methode der ProductBLL
Klasse DeleteProduct
(Klicken, um das Bild in voller Größe anzuzeigen)
Möglicherweise haben Sie bemerkt, dass die Dropdownlisten in den Registerkarten UPDATE, INSERT und DELETE bereits diese Methoden ausgewählt haben. Dies ist dank unserer Verwendung der DataObjectMethodAttribute
, die die Methoden von ProductsBLL
. Die DeleteProduct-Methode weist beispielsweise die folgende Signatur auf:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteProduct(int productID)
{
...
}
Das DataObjectMethodAttribute
Attribut gibt den Zweck jeder Methode an, unabhängig davon, ob sie zum Auswählen, Einfügen, Aktualisieren oder Löschen dient und ob es sich um den Standardwert handelt. Wenn Sie diese Attribute beim Erstellen Ihrer BLL-Klassen weggelassen haben, müssen Sie die Methoden auf den Registerkarten UPDATE, INSERT und DELETE manuell auswählen.
Nachdem Sie sichergestellt haben, dass die entsprechenden ProductsBLL
Methoden den Methoden von ObjectDataSource Insert()
Update()
zugeordnet sind, und Delete()
klicken Sie auf "Fertig stellen", um den Assistenten abzuschließen.
Untersuchen des ObjectDataSource-Markups
Wechseln Sie nach dem Konfigurieren der ObjectDataSource über den Assistenten zur Quellansicht, um das generierte deklarative Markup zu untersuchen. Das <asp:ObjectDataSource>
Tag gibt das zugrunde liegende Objekt und die aufzurufenden Methoden an. Darüber hinaus gibt DeleteParameters
es , UpdateParameters
und InsertParameters
die den Eingabeparametern für die ProductsBLL
Klassen AddProduct
- UpdateProduct
und DeleteProduct
Methoden :
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
DeleteMethod="DeleteProduct" InsertMethod="AddProduct"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
<DeleteParameters>
<asp:Parameter Name="productID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="quantityPerUnit" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="unitsInStock" Type="Int16" />
<asp:Parameter Name="unitsOnOrder" Type="Int16" />
<asp:Parameter Name="reorderLevel" Type="Int16" />
<asp:Parameter Name="discontinued" Type="Boolean" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="quantityPerUnit" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="unitsInStock" Type="Int16" />
<asp:Parameter Name="unitsOnOrder" Type="Int16" />
<asp:Parameter Name="reorderLevel" Type="Int16" />
<asp:Parameter Name="discontinued" Type="Boolean" />
</InsertParameters>
</asp:ObjectDataSource>
Die ObjectDataSource enthält einen Parameter für jeden der Eingabeparameter für die zugehörigen Methoden, genau wie eine Liste von SelectParameter
n, wenn die ObjectDataSource so konfiguriert ist, dass eine Auswahlmethode aufgerufen wird, die einen Eingabeparameter erwartet (z. B GetProductsByCategoryID(categoryID)
. ). Wie wir in Kürze sehen, werden Werte für diese DeleteParameters
, UpdateParameters
und InsertParameters
werden automatisch von gridView, DetailsView und FormView festgelegt, bevor die ObjectDataSource Insert()
-, - Update()
oder Delete()
-Methode aufrufen. Diese Werte können auch programmgesteuert nach Bedarf festgelegt werden, da wir in einem zukünftigen Lernprogramm diskutieren werden.
Ein Nebeneffekt der Verwendung des Assistenten zum Konfigurieren von ObjectDataSource ist, dass Visual Studio die OldValuesParameterFormatString-Eigenschaft auf original_{0}
. Dieser Eigenschaftswert wird verwendet, um die ursprünglichen Werte der zu bearbeitenden Daten einzuschließen und ist in zwei Szenarien nützlich:
- Wenn Benutzer beim Bearbeiten eines Datensatzes den Primärschlüsselwert ändern können. In diesem Fall müssen sowohl der neue Primärschlüsselwert als auch der ursprüngliche Primärschlüsselwert angegeben werden, damit der Datensatz mit dem ursprünglichen Primärschlüsselwert gefunden und dessen Wert entsprechend aktualisiert wird.
- Bei Verwendung optimistischer Parallelität. Optimistische Parallelität ist eine Technik, um sicherzustellen, dass zwei gleichzeitige Benutzer die Änderungen eines anderen nicht überschreiben und das Thema für ein zukünftiges Lernprogramm sind.
Die OldValuesParameterFormatString
Eigenschaft gibt den Namen der Eingabeparameter in den Aktualisierungs- und Löschmethoden des zugrunde liegenden Objekts für die ursprünglichen Werte an. Wir werden diese Eigenschaft und ihren Zweck genauer besprechen, wenn wir optimistische Parallelität untersuchen. Ich bringe es jetzt jedoch auf, da unsere BLL-Methoden nicht die ursprünglichen Werte erwarten und daher wichtig ist, dass wir diese Eigenschaft entfernen. Wenn die OldValuesParameterFormatString
Eigenschaft auf einen anderen Wert als den Standardwert ({0}
) festgelegt wird, tritt ein Fehler auf, wenn ein Datenwebsteuerelement versucht, die Methoden oder Delete()
Methoden von ObjectDataSource aufzurufen, da die ObjectDataSource Update()
versucht, sowohl die parameter DeleteParameters
als auch die UpdateParameters
ursprünglichen Wertparameter zu übergeben.
Wenn dies in dieser Zeit nicht schrecklich klar ist, machen Sie sich keine Sorgen, wir werden diese Eigenschaft und ihr Dienstprogramm in einem zukünftigen Lernprogramm untersuchen. Vorerst müssen Sie diese Eigenschaftsdeklaration nur vollständig aus der deklarativen Syntax entfernen oder den Wert auf den Standardwert ({0}) festlegen.
Hinweis
Wenn Sie einfach den OldValuesParameterFormatString
Eigenschaftswert aus dem Eigenschaftenfenster in der Entwurfsansicht löschen, ist die Eigenschaft weiterhin in der deklarativen Syntax vorhanden, aber auf eine leere Zeichenfolge festgelegt. Dies wird leider immer noch zu dem oben erörterten Problem führen. Entfernen Sie daher entweder die Eigenschaft vollständig aus der deklarativen Syntax, oder legen Sie den Wert aus der Eigenschaftenfenster auf den Standardwert fest. {0}
Schritt 3: Hinzufügen eines Datenwebsteuerelements und Konfigurieren eines Datenwebsteuerelements für die Datenänderung
Nachdem die ObjectDataSource der Seite hinzugefügt und konfiguriert wurde, können wir der Seite Datenwebsteuerelemente hinzufügen, um die Daten anzuzeigen und dem Endbenutzer eine Möglichkeit zum Ändern der Daten bereitzustellen. Wir werden die GridView, DetailsView und FormView separat betrachten, da sich diese Datenwebsteuerelemente in ihren Datenänderungsfunktionen und der Konfiguration unterscheiden.
Wie wir im restlichen Teil dieses Artikels sehen, ist das Hinzufügen von sehr einfachen Bearbeitungs-, Einfüge- und Löschunterstützung über die GridView-, DetailsView- und FormView-Steuerelemente wirklich so einfach wie das Überprüfen einiger Kontrollkästchen. Es gibt viele Subtilitäts- und Edgefälle in der realen Welt, die die Bereitstellung solcher Funktionen stärker als nur Punkt und Klick ermöglichen. Dieses Lernprogramm konzentriert sich jedoch ausschließlich auf den Nachweis einfacher Datenänderungsfunktionen. Zukünftige Lernprogramme werden Bedenken untersuchen, die zweifellos in einer realen Umgebung auftreten werden.
Löschen von Daten aus der GridView
Ziehen Sie zunächst eine GridView aus der Toolbox auf den Designer. Binden Sie als Nächstes objectDataSource an gridView, indem Sie sie aus der Dropdownliste im Smarttag von GridView auswählen. An diesem Punkt lautet das deklarative Markup von GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False"
ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel"
HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
<asp:BoundField DataField="CategoryName"
HeaderText="CategoryName" ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="SupplierName" ReadOnly="True"
SortExpression="SupplierName" />
</Columns>
</asp:GridView>
Das Binden von GridView an objectDataSource über das Smarttag hat zwei Vorteile:
- BoundFields und CheckBoxFields werden automatisch für jedes der felder erstellt, die von ObjectDataSource zurückgegeben werden. Darüber hinaus werden die Eigenschaften "BoundField" und "CheckBoxField" basierend auf den Metadaten des zugrunde liegenden Felds festgelegt. Beispielsweise werden die
ProductID
FelderCategoryName
undSupplierName
Felder als schreibgeschützt gekennzeichnetProductsDataTable
und sollten daher beim Bearbeiten nicht aktualisierbar sein. Um dies zu berücksichtigen, werden die ReadOnly-Eigenschaften dieser BoundFields auf .true
- Die DataKeyNames-Eigenschaft wird den Primärschlüsselfeldern des zugrunde liegenden Objekts zugewiesen. Dies ist für die Verwendung von GridView zum Bearbeiten oder Löschen von Daten unerlässlich, da diese Eigenschaft das Feld (oder die Gruppe von Feldern) angibt, das jeden Datensatz eindeutig identifiziert. Weitere Informationen zur
DataKeyNames
Eigenschaft finden Sie im Master/Detail-Lernprogramm mithilfe eines auswählbaren Master-GridView-Lernprogramms .
Die GridView kann zwar über die Eigenschaftenfenster- oder deklarative Syntax an die ObjectDataSource gebunden werden. Dazu müssen Sie das entsprechende BoundField und DataKeyNames
Markup manuell hinzufügen.
Das GridView-Steuerelement bietet integrierte Unterstützung für die Bearbeitung und Löschung auf Zeilenebene. Konfigurieren einer GridView zur Unterstützung des Löschens wird eine Spalte mit Schaltflächen zum Löschen hinzugefügt. Wenn der Endbenutzer auf die Schaltfläche "Löschen" für eine bestimmte Zeile klickt, folgt ein Postback, und die GridView führt die folgenden Schritte aus:
- Der Wert(n) der
DeleteParameters
ObjectDataSource wird zugewiesen. - Die Methode von
Delete()
ObjectDataSource wird aufgerufen, und der angegebene Datensatz wird gelöscht. - Das GridView-Objekt wird durch Aufrufen der
Select()
Methode erneut an die ObjectDataSource gebunden.
Die dem Feld(n) zugewiesenen DeleteParameters
Werte sind die Werte DataKeyNames
für die Zeile, auf deren Schaltfläche "Löschen" geklickt wurde. Daher ist es wichtig, dass die Eigenschaft eines GridView-Steuerelements DataKeyNames
ordnungsgemäß festgelegt wird. Wenn sie fehlt, wird dem DeleteParameters
Wert in Schritt 1 ein null
Wert zugewiesen, der wiederum nicht zu gelöschten Datensätzen in Schritt 2 führt.
Hinweis
Die DataKeys
Auflistung wird im GridView-Steuerelementzustand gespeichert, was bedeutet, dass die DataKeys
Werte über postback hinweg gespeichert werden, auch wenn der Ansichtszustand von GridView deaktiviert wurde. Es ist jedoch sehr wichtig, dass der Ansichtszustand für GridViews aktiviert bleibt, die das Bearbeiten oder Löschen unterstützen (das Standardverhalten). Wenn Sie die GridView-Eigenschaft EnableViewState
auf false
"GridView" festlegen, funktioniert das Bearbeitungs- und Löschverhalten für einen einzelnen Benutzer einwandfrei, aber wenn gleichzeitige Benutzer Daten löschen, besteht die Möglichkeit, dass diese gleichzeitigen Benutzer Datensätze versehentlich löschen oder bearbeiten können, die sie nicht beabsichtigt haben.
Diese Warnung gilt auch für DetailsViews und FormViews.
Wenn Sie einer GridView Löschfunktionen hinzufügen möchten, wechseln Sie einfach zu seinem Smarttag, und aktivieren Sie das Kontrollkästchen "Löschen aktivieren".
Abbildung 10: Aktivieren des Kontrollkästchens "Löschen aktivieren"
Wenn Sie das Kontrollkästchen "Löschen aktivieren" aus dem Smarttag aktivieren, wird der GridView ein CommandField hinzugefügt. Das CommandField rendert eine Spalte in gridView mit Schaltflächen zum Ausführen einer oder mehrerer der folgenden Aufgaben: Auswählen eines Datensatzes, Bearbeiten eines Datensatzes und Löschen eines Datensatzes. Wir haben zuvor das CommandField in Aktion mit der Auswahl von Datensätzen im Master/Detail mithilfe einer auswählbaren Master-GridView mit einem DetailView-Lernprogramm gesehen.
Das CommandField enthält eine Reihe von ShowXButton
Eigenschaften, die angeben, welche Reihe von Schaltflächen im CommandField angezeigt werden. Durch Aktivieren des Kontrollkästchens "Löschen aktivieren" wird ein CommandField aktiviert, dessen ShowDeleteButton
Eigenschaft true
der Columns-Auflistung von GridView hinzugefügt wurde.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
... BoundFields removed for brevity ...
</Columns>
</asp:GridView>
An diesem Punkt glauben Sie es, oder nicht, wir haben mit dem Hinzufügen von Löschunterstützung zur GridView fertig! Wie in Abbildung 11 dargestellt, ist beim Besuch dieser Seite über einen Browser eine Spalte mit Schaltflächen zum Löschen vorhanden.
Abbildung 11: Das CommandField fügt eine Spalte mit Löschschaltflächen hinzu (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Wenn Sie dieses Lernprogramm von Grund auf selbst erstellt haben, löst das Testen dieser Seite beim Klicken auf die Schaltfläche "Löschen" eine Ausnahme aus. Lesen Sie weiter, um zu erfahren, warum diese Ausnahmen ausgelöst wurden und wie sie behoben werden.
Hinweis
Wenn Sie dem Download folgen, der dieses Lernprogramm begleitet, wurden diese Probleme bereits berücksichtigt. Ich möchte Sie jedoch ermutigen, die unten aufgeführten Details zu lesen, um Probleme zu identifizieren, die auftreten können, und geeignete Problemumgehungen.
Wenn Sie beim Versuch, ein Produkt zu löschen, eine Ausnahme erhalten, deren Meldung "ObjectDataSource 'ObjectDataSource1' ähnelt" keine nicht generische Methode 'DeleteProduct' mit Parametern finden konnte: productID, original_ProductID", haben Sie wahrscheinlich vergessen, die OldValuesParameterFormatString
Eigenschaft aus der ObjectDataSource zu entfernen. Mit der OldValuesParameterFormatString
angegebenen Eigenschaft versucht objectDataSource, sowohl Parameter als auch productID
original_ProductID
Eingabeparameter an die DeleteProduct
Methode zu übergeben. DeleteProduct
akzeptiert jedoch nur einen einzelnen Eingabeparameter, daher die Ausnahme. Durch das Entfernen der OldValuesParameterFormatString
Eigenschaft (oder festlegen auf {0}
) wird die ObjectDataSource angewiesen, nicht zu versuchen, den ursprünglichen Eingabeparameter zu übergeben.
Abbildung 12: Sicherstellen, dass die OldValuesParameterFormatString
Eigenschaft gelöscht wurde (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Selbst wenn Sie die OldValuesParameterFormatString
Eigenschaft entfernt haben, erhalten Sie beim Versuch, ein Produkt mit der Meldung zu löschen, eine Ausnahme: "Die DELETE-Anweisung steht mit der REFERENCE-Einschränkung 'FK_Order_Details_Products'" in Konflikt. Die Northwind-Datenbank enthält eine Fremdschlüsseleinschränkung zwischen der Tabelle und Products
der Order Details
Tabelle, was bedeutet, dass ein Produkt nicht aus dem System gelöscht werden kann, wenn in der Order Details
Tabelle mindestens ein Datensatz vorhanden ist. Da jedes Produkt in der Northwind-Datenbank mindestens einen Datensatz enthält Order Details
, können wir keine Produkte löschen, bis wir zuerst die zugehörigen Auftragsdetails des Produkts löschen.
Abbildung 13: Eine Fremdschlüsseleinschränkung verbietet das Löschen von Produkten (Klicken, um das Bild in voller Größe anzuzeigen)
Für unser Lernprogramm löschen wir einfach alle Datensätze aus der Order Details
Tabelle. In einer realen Anwendung müssten wir eine der folgenden Aktionen ausführen:
- Verwenden eines weiteren Bildschirms zum Verwalten von Bestelldetails
- Erweitern Sie die
DeleteProduct
Methode, um Logik zum Löschen der Bestelldetails des angegebenen Produkts einzuschließen. - Ändern der SQL-Abfrage, die vom TableAdapter verwendet wird, um das Löschen der Bestelldetails des angegebenen Produkts einzuschließen
Löschen wir einfach alle Datensätze aus der Order Details
Tabelle, um die Fremdschlüsseleinschränkung zu umgehen. Wechseln Sie in Visual Studio zum Server-Explorer, klicken Sie mit der rechten Maustaste auf den NORTHWND.MDF
Knoten, und wählen Sie "Neue Abfrage" aus. Führen Sie dann im Abfragefenster die folgende SQL-Anweisung aus: DELETE FROM [Order Details]
Abbildung 14: Löschen aller Datensätze aus der Order Details
Tabelle (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Nach dem Löschen der Order Details
Tabelle, die auf die Schaltfläche "Löschen" klickt, wird das Produkt ohne Fehler gelöscht. Wenn sie auf die Schaltfläche "Löschen" klicken, wird das Produkt nicht gelöscht, um sicherzustellen, dass die Eigenschaft von DataKeyNames
GridView auf das Primärschlüsselfeld (ProductID
) festgelegt ist.
Hinweis
Wenn Sie auf die Schaltfläche "Löschen" klicken, folgt ein Postback, und der Datensatz wird gelöscht. Dies kann gefährlich sein, da es leicht ist, versehentlich auf die Schaltfläche "Löschen" der falschen Zeile zu klicken. In einem zukünftigen Lernprogramm erfahren Sie, wie Sie beim Löschen eines Datensatzes eine clientseitige Bestätigung hinzufügen.
Bearbeiten von Daten mit gridView
Zusammen mit dem Löschen bietet das GridView-Steuerelement auch integrierte Unterstützung für die Bearbeitung auf Zeilenebene. Durch das Konfigurieren einer GridView zur Unterstützung der Bearbeitung wird eine Spalte mit Bearbeitungsschaltflächen hinzugefügt. Aus Sicht des Endbenutzers bewirkt das Klicken auf die Schaltfläche "Bearbeiten" der Zeile, dass diese Zeile bearbeitbar wird und die Zellen in Textfelder umgewandelt werden, die die vorhandenen Werte enthalten, und die Schaltfläche "Bearbeiten" durch die Schaltflächen "Aktualisieren" und "Abbrechen" ersetzen. Nachdem sie ihre gewünschten Änderungen vorgenommen haben, kann der Endbenutzer auf die Schaltfläche "Aktualisieren" klicken, um die Änderungen zu übernehmen, oder auf die Schaltfläche "Abbrechen", um sie zu verwerfen. In beiden Fällen kehrt die GridView nach dem Klicken auf "Aktualisieren" oder "Abbrechen" zum Vorbearbeitungszustand zurück.
Wenn der Endbenutzer auf die Schaltfläche "Bearbeiten" für eine bestimmte Zeile klickt, führt ein Postback aus unserer Sicht als Seitenentwickler die folgenden Schritte aus:
- Die GridView-Eigenschaft
EditItemIndex
wird dem Index der Zeile zugewiesen, auf deren Schaltfläche "Bearbeiten" geklickt wurde. - Das GridView-Objekt wird durch Aufrufen der
Select()
Methode erneut an die ObjectDataSource gebunden. - Der Zeilenindex, der dem
EditItemIndex
entspricht, wird im "Bearbeitungsmodus" gerendert. In diesem Modus wird die Schaltfläche "Bearbeiten" durch die Schaltflächen "Aktualisieren" und "Abbrechen" und "BoundFields" ersetzt, derenReadOnly
Eigenschaften "False" (Standard) als TextBox-Websteuerelemente gerendert werden, derenText
Eigenschaften den Werten der Datenfelder zugewiesen sind.
An diesem Punkt wird das Markup an den Browser zurückgegeben, sodass der Endbenutzer änderungen an den Daten der Zeile vornehmen kann. Wenn der Benutzer auf die Schaltfläche "Aktualisieren" klickt, tritt ein Postback auf, und gridView führt die folgenden Schritte aus:
- Dem Wert(n) des
UpdateParameters
ObjectDataSource werden die vom Endbenutzer in die Bearbeitungsoberfläche von GridView eingegebenen Werte zugewiesen. - Die Methode von
Update()
ObjectDataSource wird aufgerufen, und der angegebene Datensatz wird aktualisiert. - Das GridView-Objekt wird durch Aufrufen der
Select()
Methode erneut an die ObjectDataSource gebunden.
Die in Schritt 1 zugewiesenen UpdateParameters
Primärschlüsselwerte stammen aus den in der DataKeyNames
Eigenschaft angegebenen Werten, während die Nicht-Primärschlüsselwerte aus dem Text in den TextBox-Websteuerelementen für die bearbeitete Zeile stammen. Wie beim Löschen ist es wichtig, dass die Eigenschaft eines GridView-Steuerelements DataKeyNames
ordnungsgemäß festgelegt wird. Fehlt dieser Wert, wird dem UpdateParameters
Primärschlüsselwert in Schritt 1 ein null
Wert zugewiesen, der wiederum nicht zu aktualisierten Datensätzen in Schritt 2 führt.
Bearbeitungsfunktionen können aktiviert werden, indem sie einfach das Kontrollkästchen "Bearbeitung aktivieren" im Smarttag von GridView aktivieren.
Abbildung 15: Aktivieren des Kontrollkästchens "Bearbeitung aktivieren"
Wenn Sie das Kontrollkästchen "Bearbeitung aktivieren" aktivieren, wird ein CommandField (falls erforderlich) hinzugefügt und dessen ShowEditButton
Eigenschaft auf . true
festgelegt. Wie wir bereits gesehen haben, enthält das CommandField eine Reihe von ShowXButton
Eigenschaften, die angeben, welche Reihe von Schaltflächen im CommandField angezeigt werden. Durch Aktivieren des Kontrollkästchens "Bearbeitung aktivieren" wird die ShowEditButton
Eigenschaft zum vorhandenen CommandField hinzugefügt:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True" />
... BoundFields removed for brevity ...
</Columns>
</asp:GridView>
Das ist alles, was es gibt, um eine rudimentäre Bearbeitungsunterstützung hinzuzufügen. Wie In Abbildung 16 dargestellt, ist die Bearbeitungsschnittstelle eher unformatiert jedes BoundField, dessen ReadOnly
Eigenschaft auf (standard) festgelegt false
ist, als TextBox gerendert wird. Dazu gehören Felder wie CategoryID
und SupplierID
, die Schlüssel zu anderen Tabellen sind.
Abbildung 16: Klicken auf die Schaltfläche "Chai s Bearbeiten" zeigt die Zeile im Bearbeitungsmodus an (Klicken, um das Bild in voller Größe anzuzeigen)
Zusätzlich zur direkten Bearbeitung von Fremdschlüsselwerten fehlt die Benutzeroberfläche der Bearbeitungsschnittstelle wie folgt:
- Wenn der Benutzer eine
CategoryID
oderSupplierID
das in der Datenbank nicht vorhanden ist, verstößt derUPDATE
Benutzer gegen eine Fremdschlüsseleinschränkung, wodurch eine Ausnahme ausgelöst wird. - Die Bearbeitungsschnittstelle enthält keine Überprüfung. Wenn Sie keinen erforderlichen Wert (z
ProductName
. B. ) angeben oder einen Zeichenfolgenwert eingeben, bei dem ein numerischer Wert erwartet wird (z. B. "Zu viel!" in dasUnitPrice
Textfeld eingeben), wird eine Ausnahme ausgelöst. In einem zukünftigen Lernprogramm wird das Hinzufügen von Überprüfungssteuerelementen zur Bearbeitungs-Benutzeroberfläche untersucht. - Derzeit müssen alle Produktfelder, die nicht schreibgeschützt sind, in gridView enthalten sein. Wenn wir ein Feld aus der GridView entfernen würden, z
UnitPrice
. B. beim Aktualisieren der Daten, würde gridView denUnitPrice
UpdateParameters
Wert nicht festlegen, wodurch der DatenbankdatensatzUnitPrice
in einenNULL
Wert geändert würde. Wenn ein erforderliches Feld, zProductName
. B. , aus der GridView entfernt wird, schlägt die Aktualisierung mit derselben oben erwähnten Ausnahme "Spalte "ProductName" keine NULL-Ausnahme zu. - Die Formatierung der Bearbeitungsschnittstelle bleibt viel zu wünschen. Dies
UnitPrice
wird mit vier Dezimalstellen angezeigt. Im Idealfall enthalten dieCategoryID
WerteSupplierID
DropDownLists, die die Kategorien und Lieferanten im System auflisten.
Dies sind alle Mängel, mit denen wir jetzt leben müssen, werden aber in zukünftigen Lernprogrammen behandelt.
Einfügen, Bearbeiten und Löschen von Daten mit der DetailsView
Wie wir in früheren Lernprogrammen gesehen haben, zeigt das DetailView-Steuerelement jeweils einen Datensatz an und ermöglicht wie gridView das Bearbeiten und Löschen des aktuell angezeigten Datensatzes. Sowohl die Oberfläche des Endbenutzers mit dem Bearbeiten als auch Löschen von Elementen aus einer DetailsView und dem Workflow von der ASP.NET Seite ist identisch mit der des GridView. Wo sich die DetailsView von der GridView unterscheidet, besteht darin, dass es auch integrierte Einfügeunterstützung bietet.
Um die Datenänderungsfunktionen von GridView zu veranschaulichen, fügen Sie zunächst eine DetailsView zur Basics.aspx
Seite oberhalb der vorhandenen GridView hinzu und binden sie über das Smarttag von DetailsView an die vorhandene ObjectDataSource. Deaktivieren Sie als Nächstes die Eigenschaften und Width
Eigenschaften von Height
DetailsView, und überprüfen Sie die Option "Paging aktivieren" aus dem Smarttag. Um die Unterstützung für Bearbeitung, Einfügen und Löschen zu aktivieren, aktivieren Sie einfach die Kontrollkästchen "Bearbeiten aktivieren", "Einfügen aktivieren" und "Löschen" im Smarttag.
Abbildung 17: Konfigurieren der DetailsView zur Unterstützung von Bearbeitung, Einfügen und Löschen
Wie bei gridView fügt das Hinzufügen von Bearbeitungs-, Einfüge- oder Löschunterstützung ein CommandField zur DetailsView hinzu, wie die folgende deklarative Syntax zeigt:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True">
<Fields>
<asp:BoundField DataField="ProductID"
HeaderText="ProductID" InsertVisible="False"
ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice"
HeaderText="UnitPrice" SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel"
HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
<asp:BoundField DataField="CategoryName"
HeaderText="CategoryName" ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="SupplierName" ReadOnly="True"
SortExpression="SupplierName" />
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
Beachten Sie, dass für "DetailsView" das CommandField standardmäßig am Ende der Columns-Auflistung angezeigt wird. Da die Felder von DetailsView als Zeilen gerendert werden, wird das CommandField als Zeile mit den Schaltflächen "Einfügen", "Bearbeiten" und "Löschen" am unteren Rand der Detailansicht angezeigt.
Abbildung 18: Konfigurieren der Detailansicht zur Unterstützung von Bearbeitung, Einfügen und Löschen (Klicken, um das Bild in voller Größe anzuzeigen)
Durch Klicken auf die Schaltfläche "Löschen" wird die gleiche Abfolge von Ereignissen wie bei gridView gestartet: ein Postback; gefolgt von der DetailsView, die die ObjectDataSource DeleteParameters
basierend auf den DataKeyNames
Werten auffüllt, und mit einem Aufruf der ObjectDataSource-Methode Delete()
abgeschlossen, die das Produkt tatsächlich aus der Datenbank entfernt. Die Bearbeitung in der DetailsView funktioniert auch in einer Weise, die mit der des GridView identisch ist.
Für das Einfügen wird dem Endbenutzer eine Schaltfläche "Neu" angezeigt, die beim Klicken auf die DetailsView im "Einfügemodus" gerendert wird. Bei "Einfügemodus" wird die Schaltfläche "Neu" durch die Schaltflächen "Einfügen" und "Abbrechen" ersetzt, und nur die BoundFields, deren InsertVisible
Eigenschaft auf (Standard) festgelegt true
ist, werden angezeigt. Diese Als automatisch inkrementellen Felder identifizierten Datenfelder, zProductID
. B. die InsertVisible-Eigenschaft, werden festgelegt, wenn die DetailsView über das Smarttag an die Datenquelle gebunden false
wird.
Wenn eine Datenquelle über das Smarttag an eine DetailsView gebunden wird, legt Visual Studio die InsertVisible
Eigenschaft false
nur für felder automatisch inkrementieren fest. Schreibgeschützte Felder wie CategoryName
und SupplierName
werden auf der Benutzeroberfläche "Einfügemodus" angezeigt, es sei denn, ihre InsertVisible
Eigenschaft ist explizit auf festgelegt false
. Nehmen Sie sich einen Moment Zeit, um die Eigenschaften dieser beiden Felder InsertVisible
auf false
, entweder über die deklarative Syntax von DetailsView oder über den Link "Felder bearbeiten" im Smarttag festzulegen. Abbildung 19 zeigt das Festlegen der InsertVisible
Eigenschaften false
durch Klicken auf den Link "Felder bearbeiten".
Abbildung 19: Northwind Traders bietet jetzt Acme Tea (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Nachdem Sie die InsertVisible
Eigenschaften festgelegt haben, zeigen Sie die Basics.aspx
Seite in einem Browser an, und klicken Sie auf die Schaltfläche "Neu". Abbildung 20 zeigt die DetailsView beim Hinzufügen eines neuen Getränks, Acme Tea, zu unserer Produktlinie.
Abbildung 20: Northwind Traders bietet jetzt Acme Tea (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Nachdem Sie die Details für Acme Tea eingegeben und auf die Schaltfläche "Einfügen" geklickt haben, folgt ein Postback, und der neue Datensatz wird der Products
Datenbanktabelle hinzugefügt. Da diese DetailsView die Produkte in der Reihenfolge auflistet, in der sie in der Datenbanktabelle vorhanden sind, müssen wir zum letzten Produkt wechseln, um das neue Produkt anzuzeigen.
Abbildung 21: Details für Acme Tea (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Hinweis
Die CurrentMode-Eigenschaft von DetailsView gibt die angezeigte Schnittstelle an und kann einen der folgenden Werte aufweisen: Edit
, , Insert
, oder ReadOnly
. Die DefaultMode-Eigenschaft gibt den Modus an, zu dem die DetailsView zurückkehrt, nachdem eine Bearbeitung oder ein Einfügevorgang abgeschlossen wurde und nützlich ist, um eine DetailsView anzuzeigen, die sich dauerhaft im Bearbeitungs- oder Einfügemodus befindet.
Der Punkt und klickt auf die Einfüge- und Bearbeitungsfunktionen der DetailsView leiden unter den gleichen Einschränkungen wie gridView: Der Benutzer muss vorhandene CategoryID
Werte SupplierID
und Werte über ein Textfeld eingeben; die Schnittstelle fehlt an einer Validierungslogik; alle Produktfelder, die keine Werte zulassen NULL
oder keinen Standardwert auf Datenbankebene haben, müssen in die Einfügeschnittstelle aufgenommen werden, Und so weiter.
Die Techniken, die wir untersuchen, um die Bearbeitungsschnittstelle von GridView in zukünftigen Artikeln zu erweitern und zu verbessern, können auch auf die Bearbeitungs- und Einfügeschnittstellen des DetailsView-Steuerelements angewendet werden.
Verwenden der FormView für eine flexiblere Benutzeroberfläche zur Datenänderung
FormView bietet integrierte Unterstützung für das Einfügen, Bearbeiten und Löschen von Daten, aber da es Vorlagen anstelle von Feldern verwendet, gibt es keinen Ort, um die BoundFields oder das CommandField hinzuzufügen, das von den GridView- und DetailsView-Steuerelementen verwendet wird, um die Datenänderungsschnittstelle bereitzustellen. Stattdessen müssen die Websteuerelemente zum Sammeln von Benutzereingaben beim Hinzufügen eines neuen Elements oder Bearbeiten eines vorhandenen Elements zusammen mit den Schaltflächen "Neu", "Bearbeiten", "Löschen", "Einfügen", "Aktualisieren" und "Abbrechen" manuell den entsprechenden Vorlagen hinzugefügt werden. Glücklicherweise erstellt Visual Studio automatisch die erforderliche Schnittstelle, wenn die FormView über die Dropdownliste in seinem Smarttag an eine Datenquelle gebunden wird.
Um diese Techniken zu veranschaulichen, fügen Sie zunächst eine FormView zur Basics.aspx
Seite hinzu, und binden Sie sie über das Smarttag von FormView bereits an die bereits erstellte ObjectDataSource. Dadurch wird ein EditItemTemplate
, InsertItemTemplate
und ItemTemplate
für die FormView mit TextBox-Websteuerelementen zum Sammeln der Eingaben und Schaltflächen-Websteuerelemente des Benutzers für die Schaltflächen "Neu", "Bearbeiten", "Löschen", "Einfügen", "Aktualisieren" und "Abbrechen" generiert. Darüber hinaus wird die FormView-Eigenschaft DataKeyNames
auf das Primärschlüsselfeld (ProductID
) des Objekts festgelegt, das von ObjectDataSource zurückgegeben wird. Überprüfen Sie abschließend die Option "Paging aktivieren" im Smarttag von FormView.
Im Folgenden wird das deklarative Markup für die FormView ItemTemplate
gezeigt, nachdem die FormView an die ObjectDataSource gebunden wurde. Standardmäßig ist jedes nicht boolesche Wertproduktfeld an die Text
Eigenschaft eines Label-Websteuerelements gebunden, während jedes boolesche Wertfeld (Discontinued
) an die Checked
Eigenschaft eines deaktivierten CheckBox-Websteuerelements gebunden ist. Damit die Schaltflächen "Neu", "Bearbeiten" und "Löschen" bestimmtes FormView-Verhalten beim Klicken auslösen können, ist es zwingend erforderlich, dass ihre CommandName
Werte auf New
, Edit
bzw Delete
.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
...
</EditItemTemplate>
<InsertItemTemplate>
...
</InsertItemTemplate>
<ItemTemplate>
ProductID:
<asp:Label ID="ProductIDLabel" runat="server"
Text='<%# Eval("ProductID") %>'></asp:Label><br />
ProductName:
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Bind("ProductName") %>'>
</asp:Label><br />
SupplierID:
<asp:Label ID="SupplierIDLabel" runat="server"
Text='<%# Bind("SupplierID") %>'>
</asp:Label><br />
CategoryID:
<asp:Label ID="CategoryIDLabel" runat="server"
Text='<%# Bind("CategoryID") %>'>
</asp:Label><br />
QuantityPerUnit:
<asp:Label ID="QuantityPerUnitLabel" runat="server"
Text='<%# Bind("QuantityPerUnit") %>'>
</asp:Label><br />
UnitPrice:
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# Bind("UnitPrice") %>'></asp:Label><br />
UnitsInStock:
<asp:Label ID="UnitsInStockLabel" runat="server"
Text='<%# Bind("UnitsInStock") %>'>
</asp:Label><br />
UnitsOnOrder:
<asp:Label ID="UnitsOnOrderLabel" runat="server"
Text='<%# Bind("UnitsOnOrder") %>'>
</asp:Label><br />
ReorderLevel:
<asp:Label ID="ReorderLevelLabel" runat="server"
Text='<%# Bind("ReorderLevel") %>'>
</asp:Label><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked='<%# Bind("Discontinued") %>'
Enabled="false" /><br />
CategoryName:
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Bind("CategoryName") %>'>
</asp:Label><br />
SupplierName:
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Bind("SupplierName") %>'>
</asp:Label><br />
<asp:LinkButton ID="EditButton" runat="server"
CausesValidation="False" CommandName="Edit"
Text="Edit">
</asp:LinkButton>
<asp:LinkButton ID="DeleteButton" runat="server"
CausesValidation="False" CommandName="Delete"
Text="Delete">
</asp:LinkButton>
<asp:LinkButton ID="NewButton" runat="server"
CausesValidation="False" CommandName="New"
Text="New">
</asp:LinkButton>
</ItemTemplate>
</asp:FormView>
In Abbildung 22 ist die FormView ItemTemplate
dargestellt, wenn sie über einen Browser angezeigt wird. Jedes Produktfeld wird mit den Schaltflächen "Neu", "Bearbeiten" und "Löschen" unten aufgeführt.
Abbildung 22: Die defaut FormView ItemTemplate
listet jedes Produktfeld zusammen mit den Schaltflächen "Neu", "Bearbeiten" und "Löschen" auf (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Wie bei "GridView" und "DetailsView" wird durch Klicken auf die Schaltfläche "Löschen" oder "Schaltfläche", "LinkButton" oder "ImageButton" geklickt, deren CommandName
Eigenschaft auf "Delete" festgelegt ist, ein Postback verursacht, die ObjectDataSource-Eigenschaft DeleteParameters
basierend auf dem Wert von FormView DataKeyNames
aufgefüllt und die Methode des Delete()
ObjectDataSource-Objekts aufgerufen.
Wenn auf die Schaltfläche "Bearbeiten" geklickt wird, wird ein Postback ausgelöst, und die Daten werden wieder an die EditItemTemplate
Bearbeitungsoberfläche gebunden, die für das Rendern der Bearbeitungsschnittstelle verantwortlich ist. Diese Schnittstelle enthält die Websteuerelemente zum Bearbeiten von Daten zusammen mit den Schaltflächen "Aktualisieren" und "Abbrechen". Die von Visual Studio generierte Standardeinstellung EditItemTemplate
enthält eine Bezeichnung für alle automatisch inkrementellen Felder (ProductID
), ein TextBox für jedes nicht boolesche Wertfeld und ein CheckBox für jedes boolesche Wertfeld. Dieses Verhalten ähnelt sehr den automatisch generierten BoundFields in den GridView- und DetailsView-Steuerelementen.
Hinweis
Ein kleines Problem mit der automatischen Generierung von FormView besteht EditItemTemplate
darin, dass textBox-Websteuerelemente für diejenigen Felder gerendert werden, die schreibgeschützt sind, z CategoryName
. B. und SupplierName
. Wir werden sehen, wie sie dies in Kürze berücksichtigen.
Die TextBox-Steuerelemente in der EditItemTemplate
Eigenschaft sind Text
mit bidirektionalem Datenbindung an den Wert des entsprechenden Datenfelds gebunden. Bidirektionale Datenbindung, die durch , bezeichnet durch <%# Bind("dataField") %>
, führt datenbindung sowohl beim Binden von Daten an die Vorlage als auch beim Auffüllen der Parameter der ObjectDataSource zum Einfügen oder Bearbeiten von Datensätzen durch. Wenn der Benutzer auf die Schaltfläche "Bearbeiten" aus der ItemTemplate
Schaltfläche klickt, gibt die Bind()
Methode den angegebenen Datenfeldwert zurück. Nachdem der Benutzer seine Änderungen vorgenommen hat und auf "Aktualisieren" klickt, werden die zurückgesetzten Werte, die den angegebenen Bind()
Datenfeldern entsprechen, auf die ObjectDataSource angewendet UpdateParameters
. Alternativ ruft die unidirektionale Datenbindung, die durch <%# Eval("dataField") %>
die Angabe gekennzeichnet wird, nur die Datenfeldwerte ab, wenn Daten an die Vorlage gebunden werden, und gibt die vom Benutzer eingegebenen Werte nicht an die Parameter der Datenquelle beim Postback zurück.
Das folgende deklarative Markup zeigt die FormViews EditItemTemplate
. Beachten Sie, dass die Bind()
Methode hier in der Datenbindungssyntax verwendet wird und dass die Websteuerelemente "Aktualisieren" und "Abbrechen"-Schaltflächen ihre CommandName
Eigenschaften entsprechend festgelegt haben.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
ProductID:
<asp:Label ID="ProductIDLabel1" runat="server"
Text="<%# Eval("ProductID") %>"></asp:Label><br />
ProductName:
<asp:TextBox ID="ProductNameTextBox" runat="server"
Text="<%# Bind("ProductName") %>">
</asp:TextBox><br />
SupplierID:
<asp:TextBox ID="SupplierIDTextBox" runat="server"
Text="<%# Bind("SupplierID") %>">
</asp:TextBox><br />
CategoryID:
<asp:TextBox ID="CategoryIDTextBox" runat="server"
Text="<%# Bind("CategoryID") %>">
</asp:TextBox><br />
QuantityPerUnit:
<asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
Text="<%# Bind("QuantityPerUnit") %>">
</asp:TextBox><br />
UnitPrice:
<asp:TextBox ID="UnitPriceTextBox" runat="server"
Text="<%# Bind("UnitPrice") %>">
</asp:TextBox><br />
UnitsInStock:
<asp:TextBox ID="UnitsInStockTextBox" runat="server"
Text="<%# Bind("UnitsInStock") %>">
</asp:TextBox><br />
UnitsOnOrder:
<asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
Text="<%# Bind("UnitsOnOrder") %>">
</asp:TextBox><br />
ReorderLevel:
<asp:TextBox ID="ReorderLevelTextBox" runat="server"
Text="<%# Bind("ReorderLevel") %>">
</asp:TextBox><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked="<%# Bind("Discontinued") %>" /><br />
CategoryName:
<asp:TextBox ID="CategoryNameTextBox" runat="server"
Text="<%# Bind("CategoryName") %>">
</asp:TextBox><br />
SupplierName:
<asp:TextBox ID="SupplierNameTextBox" runat="server"
Text="<%# Bind("SupplierName") %>">
</asp:TextBox><br />
<asp:LinkButton ID="UpdateButton" runat="server"
CausesValidation="True" CommandName="Update"
Text="Update">
</asp:LinkButton>
<asp:LinkButton ID="UpdateCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</EditItemTemplate>
<InsertItemTemplate>
...
</InsertItemTemplate>
<ItemTemplate>
...
</ItemTemplate>
</asp:FormView>
Unsere EditItemTemplate
, an diesem Punkt, führt dazu, dass eine Ausnahme ausgelöst wird, wenn wir versuchen, sie zu verwenden. Das Problem besteht darin, dass die CategoryName
Felder SupplierName
als TextBox-Websteuerelemente in der EditItemTemplate
Datei gerendert werden. Diese TextBoxes müssen entweder in Beschriftungen geändert oder vollständig entfernt werden. Löschen wir sie einfach vollständig aus dem EditItemTemplate
.
Abbildung 23 zeigt die FormView in einem Browser, nachdem auf die Schaltfläche "Bearbeiten" für "Chai" geklickt wurde. Beachten Sie, dass die SupplierName
in der ItemTemplate
Datei angezeigten Felder CategoryName
nicht mehr vorhanden sind, da wir sie soeben aus der EditItemTemplate
Datei entfernt haben. Wenn auf die Schaltfläche "Aktualisieren" geklickt wird, durchläuft die FormView dieselbe Abfolge von Schritten wie die GridView- und DetailsView-Steuerelemente.
Abbildung 23: Standardmäßig wird jedes EditItemTemplate
bearbeitbare Produktfeld als TextBox oder CheckBox angezeigt (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Wenn auf die Schaltfläche "Einfügen" geklickt wird, folgt ein Postback der FormView ItemTemplate
. Allerdings sind keine Daten an die FormView gebunden, da ein neuer Datensatz hinzugefügt wird. Die InsertItemTemplate
Schnittstelle enthält die Websteuerelemente zum Hinzufügen eines neuen Datensatzes zusammen mit den Schaltflächen "Einfügen" und "Abbrechen". Der von Visual Studio generierte Standardwert InsertItemTemplate
enthält ein TextBox-Element für jedes nicht boolesche Wertfeld und ein CheckBox-Element für jedes boolesche Wertfeld, ähnlich der automatisch generierten EditItemTemplate
Schnittstelle. Die TextBox-Steuerelemente haben ihre Text
Eigenschaft an den Wert des entsprechenden Datenfelds gebunden, indem sie bidirektionale Datenbindung verwenden.
Das folgende deklarative Markup zeigt die FormViews InsertItemTemplate
. Beachten Sie, dass die Bind()
Methode hier in der Datenbindungssyntax verwendet wird und dass die Websteuerelemente "Einfügen" und "Abbrechen, Schaltfläche" ihre CommandName
Eigenschaften entsprechend festgelegt haben.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
...
</EditItemTemplate>
<InsertItemTemplate>
ProductName:
<asp:TextBox ID="ProductNameTextBox" runat="server"
Text="<%# Bind("ProductName") %>">
</asp:TextBox><br />
SupplierID:
<asp:TextBox ID="SupplierIDTextBox" runat="server"
Text="<%# Bind("SupplierID") %>">
</asp:TextBox><br />
CategoryID:
<asp:TextBox ID="CategoryIDTextBox" runat="server"
Text="<%# Bind("CategoryID") %>">
</asp:TextBox><br />
QuantityPerUnit:
<asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
Text="<%# Bind("QuantityPerUnit") %>">
</asp:TextBox><br />
UnitPrice:
<asp:TextBox ID="UnitPriceTextBox" runat="server"
Text="<%# Bind("UnitPrice") %>">
</asp:TextBox><br />
UnitsInStock:
<asp:TextBox ID="UnitsInStockTextBox" runat="server"
Text="<%# Bind("UnitsInStock") %>">
</asp:TextBox><br />
UnitsOnOrder:
<asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
Text="<%# Bind("UnitsOnOrder") %>">
</asp:TextBox><br />
ReorderLevel:
<asp:TextBox ID="ReorderLevelTextBox" runat="server"
Text="<%# Bind("ReorderLevel") %>">
</asp:TextBox><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked="<%# Bind("Discontinued") %>" /><br />
CategoryName:
<asp:TextBox ID="CategoryNameTextBox" runat="server"
Text="<%# Bind("CategoryName") %>">
</asp:TextBox><br />
SupplierName:
<asp:TextBox ID="SupplierNameTextBox" runat="server"
Text="<%# Bind("SupplierName") %>">
</asp:TextBox><br />
<asp:LinkButton ID="InsertButton" runat="server"
CausesValidation="True" CommandName="Insert"
Text="Insert">
</asp:LinkButton>
<asp:LinkButton ID="InsertCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</InsertItemTemplate>
<ItemTemplate>
...
</ItemTemplate>
</asp:FormView>
Es gibt eine Subtilität mit der automatischen Generation von FormView der InsertItemTemplate
. Insbesondere werden die TextBox-Websteuerelemente auch für felder erstellt, die schreibgeschützt sind, z CategoryName
. B. und SupplierName
. Wie bei der EditItemTemplate
, müssen wir diese TextBoxes aus dem InsertItemTemplate
.
Abbildung 24 zeigt die FormView in einem Browser beim Hinzufügen eines neuen Produkts, Acme Coffee. Beachten Sie, dass die SupplierName
in der ItemTemplate
Datei angezeigten Felder CategoryName
nicht mehr vorhanden sind, da wir sie soeben entfernt haben. Wenn auf die Schaltfläche "Einfügen" geklickt wird, durchläuft die FormView dieselbe Abfolge von Schritten wie das DetailsView-Steuerelement, und fügen Sie der Products
Tabelle einen neuen Datensatz hinzu. Abbildung 25 zeigt die Details des Acme Coffee-Produkts in der FormView, nachdem es eingefügt wurde.
Abbildung 24: Diktieren InsertItemTemplate
der Einfügeschnittstelle des Formularansichts (Klicken, um das Bild in voller Größe anzuzeigen)
Abbildung 25: Die Details für neues Produkt, Acme Coffee, werden in der FormView angezeigt (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Durch das Trennen der schreibgeschützten, bearbeitungsgeschützten und einzufügenden Schnittstellen in drei separate Vorlagen ermöglicht die FormView eine bessere Kontrolle über diese Schnittstellen als detailsView und GridView.
Hinweis
Wie die DetailsView-Eigenschaft gibt die FormView-Eigenschaft CurrentMode
die angezeigte Schnittstelle an, und seine DefaultMode
Eigenschaft gibt den Modus an, zu dem die FormView zurückkehrt, nachdem eine Bearbeitung oder ein Einfügen abgeschlossen wurde.
Zusammenfassung
In diesem Lernprogramm haben wir die Grundlagen des Einfügens, Bearbeitens und Löschens von Daten mithilfe von GridView, DetailsView und FormView untersucht. Alle drei Steuerelemente bieten eine gewisse Ebene integrierter Datenänderungsfunktionen, die verwendet werden können, ohne eine einzelne Codezeile in der ASP.NET Seite dank der Datenwebsteuerelemente und der ObjectDataSource zu schreiben. Die einfachen Point- und Click-Techniken rendern jedoch eine ziemlich gebrechene und naive Datenänderungs-Benutzeroberfläche. Um eine Überprüfung bereitzustellen, programmgesteuerte Werte einzugeben, Ausnahmen ordnungsgemäß zu behandeln, die Benutzeroberfläche anzupassen usw., müssen wir uns auf eine Vielzahl von Techniken verlassen, die in den nächsten Lernprogrammen behandelt werden.
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