Freigeben über


Eine Übersicht über das Einfügen, Aktualisieren und Löschen von Daten (C#)

von Scott Mitchell

PDF herunterladen

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).

Die Methoden

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

Hinzufügen der ASP.NET Seiten für die datenänderungsbezogenen Lernprogramme

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.

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

Abbildung 3: Hinzufügen des SectionLevelTutorialListing.ascx Benutzersteuerelements zu Default.aspx (Klicken, um das Bild in voller Größe anzuzeigen)

Fügen Sie schließlich die Seiten als Einträge zur Web.sitemap Datei hinzu. Fügen Sie insbesondere das folgende Markup nach der 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.sitemapeinen 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.

Die Websiteübersicht enthält jetzt Einträge für das Bearbeiten, 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.

Konfigurieren der ObjectDataSource für die Verwendung der ProductsBLL-Klasse

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.

Alle Produkte von ObjectDataSource zurückgeben

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 AddProductUpdateProductbzwDeleteProduct. methoden aufgerufen werden.

Zuordnen der Update()-Methode von ObjectDataSource zur UpdateProduct-Methode der ProductBLL-Klasse

Abbildung 7: Zuordnen der Methode von ObjectDataSource Update() zur Methode der ProductBLL Klasse UpdateProduct (Klicken, um das Bild in voller Größe anzuzeigen)

Zuordnen der Insert()-Methode der AddProduct-Methode der ProductBLL-Klasse

Abbildung 8: Zuordnen der Methode von ObjectDataSource Insert() zur Add-Methode Product der ProductBLL Klasse (Klicken, um das Bild in voller Größe anzuzeigen)

Zuordnen der Delete()-Methode von ObjectDataSource zur DeleteProduct-Methode der ProductBLL-Klasse

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 DeleteParameterses , UpdateParametersund InsertParameters die den Eingabeparametern für die ProductsBLL Klassen AddProduct- UpdateProductund 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, UpdateParametersund 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 ProductIDFelder CategoryNameund SupplierName Felder als schreibgeschützt gekennzeichnet ProductsDataTable 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:

  1. Der Wert(n) der DeleteParameters ObjectDataSource wird zugewiesen.
  2. Die Methode von Delete() ObjectDataSource wird aufgerufen, und der angegebene Datensatz wird gelöscht.
  3. 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".

Aktivieren des Kontrollkästchens

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.

Das CommandField fügt eine Spalte mit Schaltflächen zum Löschen hinzu.

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. DeleteProductakzeptiert 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.

Stellen Sie sicher, dass die OldValuesParameterFormatString-Eigenschaft gelöscht wurde.

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.

Eine Fremdschlüsseleinschränkung verbietet das Löschen von Produkten.

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]

Alle Datensätze aus der Tabelle

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:

  1. Die GridView-Eigenschaft EditItemIndex wird dem Index der Zeile zugewiesen, auf deren Schaltfläche "Bearbeiten" geklickt wurde.
  2. Das GridView-Objekt wird durch Aufrufen der Select() Methode erneut an die ObjectDataSource gebunden.
  3. 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, deren ReadOnly Eigenschaften "False" (Standard) als TextBox-Websteuerelemente gerendert werden, deren Text 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:

  1. Dem Wert(n) des UpdateParameters ObjectDataSource werden die vom Endbenutzer in die Bearbeitungsoberfläche von GridView eingegebenen Werte zugewiesen.
  2. Die Methode von Update() ObjectDataSource wird aufgerufen, und der angegebene Datensatz wird aktualisiert.
  3. 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.

Aktivieren des Kontrollkästchens

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.

Durch Klicken auf die Schaltfläche

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 oder SupplierID das in der Datenbank nicht vorhanden ist, verstößt der UPDATE 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 das UnitPrice 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 den UnitPrice UpdateParameters Wert nicht festlegen, wodurch der Datenbankdatensatz UnitPrice in einen NULL Wert geändert würde. Wenn ein erforderliches Feld, z ProductName. 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 die CategoryID Werte SupplierID 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.

Screenshot des Fensters

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.

Screenshot der Detailansicht mit dem CommandField, das als untere Zeile mit den Schaltflächen

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 SupplierNamewerden 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".

Screenshot des Fensters

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.

Screenshot der DetailsView der Basics.aspx-Seite in einem Webbrowser.

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.

Details zu Acme Tea

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, InsertItemTemplateund 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, Editbzw 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.

Die Defaut FormView ItemTemplate listet jedes Produktfeld zusammen mit den Schaltflächen

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 EditItemTemplateBearbeitungsoberflä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 ItemTemplateSchaltflä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 EditItemTemplateDatei 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 EditItemTemplateDatei entfernt haben. Wenn auf die Schaltfläche "Aktualisieren" geklickt wird, durchläuft die FormView dieselbe Abfolge von Schritten wie die GridView- und DetailsView-Steuerelemente.

Standardmäßig zeigt die EditItemTemplate jedes bearbeitbare Produktfeld als TextBox- oder CheckBox-Objekt an.

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 EditItemTemplateSchnittstelle. 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.

Die InsertItemTemplate diktiert die Einfügeschnittstelle von FormView

Abbildung 24: Diktieren InsertItemTemplate der Einfügeschnittstelle des Formularansichts (Klicken, um das Bild in voller Größe anzuzeigen)

Die Details für neues Produkt, Acme Coffee, werden in der FormView angezeigt.

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