Share via


Überprüfen von Ereignissen im Zusammenhang mit Vorgängen zum Einfügen, Aktualisieren und Löschen (VB)

von Scott Mitchell

PDF herunterladen

In diesem Tutorial untersuchen wir die Verwendung der Ereignisse, die vor, während und nach einem Einfüge-, Aktualisierungs- oder Löschvorgang eines ASP.NET-Datenwebsteuerelements auftreten. Außerdem erfahren Sie, wie Sie die Bearbeitungsoberfläche so anpassen, dass nur eine Teilmenge der Produktfelder aktualisiert wird.

Einführung

Wenn Sie die integrierten Einfüge-, Bearbeitungs- oder Löschungsfeatures der GridView-, DetailsView- oder FormView-Steuerelemente verwenden, werden verschiedene Schritte ausgeführt, wenn der Endbenutzer den Vorgang zum Hinzufügen eines neuen Datensatzes oder zum Aktualisieren oder Löschen eines vorhandenen Datensatzes abschließt. Wie im vorherigen Tutorial beschrieben, wird beim Bearbeiten einer Zeile in GridView die Schaltfläche Bearbeiten durch die Schaltflächen Aktualisieren und Abbrechen ersetzt, und die BoundFields werden in TextBoxes umgewandelt. Nachdem der Endbenutzer die Daten aktualisiert und auf Aktualisieren geklickt hat, werden die folgenden Schritte für das Postback ausgeführt:

  1. GridView füllt seine ObjectDataSource UpdateParameters mit den eindeutigen identifizierenden Feld(n) des bearbeiteten Datensatzes (über die DataKeyNames -Eigenschaft) zusammen mit den vom Benutzer eingegebenen Werten auf.
  2. GridView ruft die ObjectDataSource-Methode auf Update() , die wiederum die entsprechende Methode im zugrunde liegenden Objekt aufruft (ProductsDAL.UpdateProductin unserem vorherigen Tutorial).
  3. Die zugrunde liegenden Daten, die jetzt die aktualisierten Änderungen enthalten, werden an GridView zurück.

Während dieser Schrittfolge wird eine Reihe von Ereignissen ausgelöst, sodass wir Ereignishandler erstellen können, um bei Bedarf benutzerdefinierte Logik hinzuzufügen. Beispielsweise wird vor Schritt 1 das GridView-Ereignis RowUpdating ausgelöst. An diesem Punkt können wir die Updateanforderung abbrechen, wenn ein Validierungsfehler vorliegt. Wenn die Update() -Methode aufgerufen wird, wird das ObjectDataSource-Ereignis Updating ausgelöst und bietet die Möglichkeit, die Werte eines der UpdateParametershinzuzufügen oder anzupassen. Nachdem die Ausführung der Dem ObjectDataSource zugrunde liegenden ObjectDataSource-Methode abgeschlossen ist, wird das ObjectDataSource-Ereignis Updated ausgelöst. Ein Ereignishandler für das Updated Ereignis kann die Details zum Aktualisierungsvorgang überprüfen, z. B. wie viele Zeilen betroffen waren und ob eine Ausnahme aufgetreten ist. Schließlich wird nach Schritt 2 das GridView-Ereignis RowUpdated ausgelöst. Ein Ereignishandler für dieses Ereignis kann zusätzliche Informationen zum gerade ausgeführten Updatevorgang untersuchen.

Abbildung 1 zeigt diese Reihe von Ereignissen und Schritten beim Aktualisieren eines GridView-Elements. Das Ereignismuster in Abbildung 1 ist für die Aktualisierung mit einer GridView nicht eindeutig. Durch das Einfügen, Aktualisieren oder Löschen von Daten aus GridView, DetailsView oder FormView wird die gleiche Sequenz von Prä- und Post-Level-Ereignissen sowohl für das Datenwebsteuerelement als auch für die ObjectDataSource ausgelöst.

Eine Reihe von Vor- und Nachereignissen beim Aktualisieren von Daten in einer GridView

Abbildung 1: Eine Reihe von Vor- und Nachereignissen beim Aktualisieren von Daten in einem GridView-Objekt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

In diesem Tutorial untersuchen wir die Verwendung dieser Ereignisse, um die integrierten Funktionen zum Einfügen, Aktualisieren und Löschen der ASP.NET-Datenwebsteuerelemente zu erweitern. Außerdem erfahren Sie, wie Sie die Bearbeitungsoberfläche so anpassen, dass nur eine Teilmenge der Produktfelder aktualisiert wird.

Schritt 1: Aktualisieren der Felder undUnitPricedesProductNameProdukts

In den Bearbeitungsschnittstellen aus dem vorherigen Tutorial mussten alle Produktfelder, die nicht schreibgeschützt waren, einbezogen werden. Wenn wir beim Aktualisieren der Daten ein Feld aus der GridView entfernen würden, QuantityPerUnit würde das Datenwebsteuerelement den Wert der QuantityPerUnitUpdateParameters ObjectDataSource nicht festlegen. Die ObjectDataSource würde dann den Wert von Nothing an die UpdateProduct BLL-Methode (Business Logic Layer) übergeben, wodurch die Spalte des QuantityPerUnit bearbeiteten Datenbankdatensatzes in einen NULL Wert geändert würde. Wenn ein erforderliches Feld, z ProductName. B. , aus der Bearbeitungsoberfläche entfernt wird, schlägt die Aktualisierung mit der Ausnahme "Spalte 'ProductName' lässt keine NULL-Werte zu" fehl. Der Grund für dieses Verhalten war, dass ObjectDataSource für den Aufruf der -Methode der ProductsBLL Klasse UpdateProduct konfiguriert wurde, die einen Eingabeparameter für jedes Produktfeld erwartete. Daher enthielt die ObjectDataSource-Auflistung UpdateParameters einen Parameter für jeden eingabeparameter der Methode.

Wenn wir ein Datenwebsteuerelement bereitstellen möchten, das es dem Endbenutzer ermöglicht, nur eine Teilmenge von Feldern zu aktualisieren, müssen wir entweder die fehlenden UpdateParameters Werte im ObjectDataSource-Ereignishandler Updating programmgesteuert festlegen oder eine BLL-Methode erstellen und aufrufen, die nur eine Teilmenge der Felder erwartet. Lassen Sie uns diesen letztgenannten Ansatz untersuchen.

Erstellen Sie insbesondere eine Seite, auf der nur die ProductName Felder und UnitPrice in einem bearbeitbaren GridView-Objekt angezeigt werden. Die Bearbeitungsoberfläche dieser GridView ermöglicht es dem Benutzer nur, die beiden angezeigten Felder ProductName und UnitPricezu aktualisieren. Da diese Bearbeitungsschnittstelle nur eine Teilmenge der Felder eines Produkts bereitstellt, müssen wir entweder eine ObjectDataSource erstellen, die die vorhandene BLL-Methode UpdateProduct verwendet und die fehlenden Produktfeldwerte programmgesteuert im Updating Ereignishandler festgelegt hat, oder wir müssen eine neue BLL-Methode erstellen, die nur die Teilmenge der in GridView definierten Felder erwartet. Für dieses Tutorial verwenden wir die letztere Option und erstellen eine Überladung der UpdateProduct -Methode, die nur drei Eingabeparameter akzeptiert: productName, unitPriceund productID:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Update, False)> _
    Public Function UpdateProduct(productName As String, _
        unitPrice As Nullable(Of Decimal), productID As Integer) _
        As Boolean

    Dim products As Northwind.ProductsDataTable = _
        Adapter.GetProductByProductID(productID)

    If products.Count = 0 Then
        Return False
    End If

    Dim product As Northwind.ProductsRow = products(0)

    product.ProductName = productName
    If Not unitPrice.HasValue Then
        product.SetUnitPriceNull()
    Else
        product.UnitPrice = unitPrice.Value
    End If

    Dim rowsAffected As Integer = Adapter.Update(product)

    Return rowsAffected = 1
End Function

Wie bei der ursprünglichen UpdateProduct Methode beginnt diese Überladung mit der Überprüfung, ob in der Datenbank ein Produkt mit dem angegebenen ProductIDvorhanden ist. Andernfalls wird zurückgegeben False, was angibt, dass bei der Anforderung zur Aktualisierung der Produktinformationen ein Fehler aufgetreten ist. Andernfalls werden die Felder und UnitPrice des vorhandenen Produktdatensatzes ProductName entsprechend aktualisiert, und es wird ein Commit für das Update ausgeführt, indem die TableAdapter-Methode Update() aufgerufen und der ProductsRow instance übergeben wird.

Mit dieser Ergänzung zu unserer ProductsBLL Klasse können Wir die vereinfachte GridView-Schnittstelle erstellen. Öffnen Sie die DataModificationEvents.aspxEditInsertDelete im Ordner, und fügen Sie der Seite ein GridView-Element hinzu. Erstellen Sie eine neue ObjectDataSource, und konfigurieren Sie sie so, dass die ProductsBLL -Klasse mit ihrer Select() Methodenzuordnung zu GetProducts und die Update() Methodenzuordnung zu der UpdateProduct -Überladung verwendet wird, die nur die productNameEingabeparameter , unitPriceund productID akzeptiert. Abbildung 2 zeigt den Assistenten zum Erstellen von Datenquellen, wenn die ObjectDataSource-Methode Update() der neuen UpdateProduct Methodenüberladung der ProductsBLL Klasse zugeordnet wird.

Zuordnen der Update()-Methode von ObjectDataSource zur neuen UpdateProduct-Überladung

Abbildung 2: Zuordnen der ObjectDataSource-Methode Update() zur neuen UpdateProduct Überladung (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Da in unserem Beispiel zunächst nur die Möglichkeit zum Bearbeiten von Daten, aber nicht zum Einfügen oder Löschen von Datensätzen benötigt wird, nehmen Sie sich einen Moment Zeit, um explizit anzugeben, dass die Methoden von ObjectDataSource Insert() und Delete() keiner der Methoden der ProductsBLL Klasse zugeordnet werden sollen, indem Sie zu den Registerkarten INSERT und DELETE wechseln und in der Dropdownliste (Keine) auswählen.

Wählen Sie (Keine) aus der Drop-Down liste für die Registerkarten INSERT und DELETE aus.

Abbildung 3: Wählen Sie (Keine) aus der Drop-Down Liste für die Registerkarten INSERT und DELETE aus (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Aktivieren Sie nach Abschluss dieses Assistenten das Kontrollkästchen Bearbeitung aktivieren über das Smarttag von GridView.

Nach Abschluss des Assistenten zum Erstellen von Datenquellen und der Bindung an GridView hat Visual Studio die deklarative Syntax für beide Steuerelemente erstellt. Wechseln Sie zur Quellansicht, um das deklarative Markup von ObjectDataSource zu untersuchen, wie unten gezeigt:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Da keine Zuordnungen für die ObjectDataSource-Methoden Insert() und Delete() vorhanden sind, gibt es keine InsertParameters Abschnitte oder DeleteParameters . Da die Update() Methode der Methodenüberladung zugeordnet ist, die UpdateProduct nur drei Eingabeparameter akzeptiert, enthält der UpdateParameters Abschnitt nur drei Parameter Instanzen.

Beachten Sie, dass die ObjectDataSource-Eigenschaft OldValuesParameterFormatString auf original_{0}festgelegt ist. Diese Eigenschaft wird automatisch von Visual Studio festgelegt, wenn Sie den Assistenten zum Konfigurieren von Datenquellen verwenden. Da unsere BLL-Methoden jedoch nicht erwarten, dass der ursprüngliche ProductID Wert übergeben wird, entfernen Sie diese Eigenschaftszuweisung vollständig aus der deklarativen Syntax von ObjectDataSource.

Hinweis

Wenn Sie einfach den Eigenschaftswert aus dem OldValuesParameterFormatString Eigenschaftenfenster in der Entwurfsansicht löschen, ist die Eigenschaft weiterhin in der deklarativen Syntax vorhanden, wird aber auf eine leere Zeichenfolge festgelegt. Entfernen Sie entweder die Eigenschaft vollständig aus der deklarativen Syntax, oder legen Sie den Wert aus der Eigenschaftenfenster auf den Standardwert fest{0}.

Während die ObjectDataSource nur UpdateParameters für den Namen, den Preis und die ID des Produkts enthält, hat Visual Studio in der GridView für jedes Produktfeld ein BoundField oder CheckBoxField hinzugefügt.

GridView enthält ein BoundField- oder CheckBoxField-Element für jedes der Felder des Produkts.

Abbildung 4: GridView enthält ein BoundField- oder CheckBoxField für jedes Der Felder des Produkts (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Wenn der Endbenutzer ein Produkt bearbeitet und auf die Schaltfläche Aktualisieren klickt, listet GridView die Felder auf, die nicht schreibgeschützt waren. Anschließend wird der Wert des entsprechenden Parameters in der ObjectDataSource-Auflistung UpdateParameters auf den vom Benutzer eingegebenen Wert festgelegt. Wenn kein entsprechender Parameter vorhanden ist, fügt GridView einen parameter zur Auflistung hinzu. Wenn gridView also BoundFields und CheckBoxFields für alle Felder des Produkts enthält, wird die ObjectDataSource am Ende die Überladung aufrufen, die UpdateProduct alle diese Parameter akzeptiert, obwohl das deklarative Markup der ObjectDataSource nur drei Eingabeparameter angibt (siehe Abbildung 5). Wenn in GridView eine Kombination von nicht schreibgeschützten Produktfeldern vorhanden ist, die nicht den Eingabeparametern für eine UpdateProduct Überladung entspricht, wird beim Versuch, eine Aktualisierung durchzuführen, eine Ausnahme ausgelöst.

GridView fügt der UpdateParameters-Auflistung von ObjectDataSource Parameter hinzu.

Abbildung 5: Die GridView fügt der ObjectDataSource-Auflistung UpdateParameters Parameter hinzu (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Um sicherzustellen, dass die ObjectDataSource die UpdateProduct Überladung aufruft, die nur den Namen, den Preis und die ID des Produkts akzeptiert, müssen wir GridView auf bearbeitbare Felder nur für und ProductNameUnitPricebeschränken. Dies kann erreicht werden, indem die anderen BoundFields und CheckBoxFields entfernt werden, indem die Eigenschaft dieser anderen Felder ReadOnly auf Truefestgelegt wird, oder durch eine Kombination aus beiden. In diesem Tutorial entfernen wir einfach alle GridView-Felder mit Ausnahme von ProductName Und UnitPrice BoundFields. Danach sieht das deklarative Markup von GridView wie folgt aus:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>

Obwohl die UpdateProduct Überladung drei Eingabeparameter erwartet, gibt es in gridView nur zwei BoundFields. Dies liegt daran, dass der productID Eingabeparameter ein Primärschlüsselwert ist und über den Wert der DataKeyNames -Eigenschaft für die bearbeitete Zeile übergeben wird.

Unsere GridView ermöglicht es einem Benutzer zusammen mit der UpdateProduct Überladung, nur den Namen und den Preis eines Produkts zu bearbeiten, ohne eines der anderen Produktfelder zu verlieren.

Die Schnittstelle ermöglicht die Bearbeitung nur des Produktnamens und des Preises.

Abbildung 6: Die Schnittstelle ermöglicht die Bearbeitung nur des Produktnamens und des Preises (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Hinweis

Wie im vorherigen Tutorial erläutert, ist es von entscheidender Bedeutung, dass der Ansichtszustand von GridView aktiviert ist (das Standardverhalten). Wenn Sie die GridView-Eigenschaft EnableViewState auf falsefestlegen, besteht das Risiko, dass gleichzeitige Benutzer datensätze versehentlich löschen oder bearbeiten.

Verbessern derUnitPriceFormatierung

Während das In Abbildung 6 gezeigte GridView-Beispiel funktioniert, ist das UnitPrice Feld überhaupt nicht formatiert, was zu einer Preisanzeige führt, die keine Währungssymbole enthält und vier Dezimalstellen aufweist. Um eine Währungsformatierung für die nicht bearbeitbaren Zeilen anzuwenden, legen Sie einfach die Eigenschaft von UnitPriceDataFormatString BoundField auf {0:c} und ihre HtmlEncode -Eigenschaft auf fest False.

Legen Sie die Eigenschaften DataFormatString und HtmlEncode von UnitPrice entsprechend fest.

Abbildung 7: Legen Sie die UnitPriceEigenschaften von DataFormatString und HtmlEncode entsprechend fest (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Mit dieser Änderung formatieren die nicht bearbeitbaren Zeilen den Preis als Währung; Die bearbeitete Zeile zeigt jedoch weiterhin den Wert ohne Währungssymbol und mit vier Dezimalstellen an.

Die nicht bearbeitbaren Zeilen werden jetzt als Währungswerte formatiert.

Abbildung 8: Die nicht bearbeitbaren Zeilen sind jetzt als Währungswerte formatiert (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Die in der DataFormatString -Eigenschaft angegebenen Formatierungsanweisungen können auf die Bearbeitungsschnittstelle ApplyFormatInEditMode angewendet werden, indem die BoundField-Eigenschaft auf True festgelegt wird (der Standardwert ist False). Nehmen Sie sich einen Moment Zeit, um diese Eigenschaft auf festzulegen True.

Legen Sie die ApplyFormatInEditMode-Eigenschaft von UnitPrice BoundField auf True fest.

Abbildung 9: Festlegen der UnitPrice BoundField-Eigenschaft ApplyFormatInEditMode auf True (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Mit dieser Änderung wird der Wert der UnitPrice in der bearbeiteten Zeile angezeigten auch als Währung formatiert.

Screenshot: GridView mit dem UnitPrice-Wert der bearbeiteten Zeile, der als Währung formatiert ist.

Abbildung 10: Der Wert der UnitPrice bearbeiteten Zeile ist jetzt als Währung formatiert (Klicken Sie, um das bild in voller Größe anzuzeigen)

Das Aktualisieren eines Produkts mit dem Währungssymbol im Textfeld, z. B. 19,00 USD, löst jedoch eine aus FormatException. Wenn GridView versucht, die vom Benutzer bereitgestellten Werte der ObjectDataSource-Auflistung UpdateParameters zuzuweisen, kann die UnitPrice Zeichenfolge "$19.00" nicht in die Decimal vom Parameter erforderliche konvertiert werden (siehe Abbildung 11). Um dies zu beheben, können wir einen Ereignishandler für das GridView-Ereignis RowUpdating erstellen und den vom Benutzer bereitgestellten UnitPrice als währungs formatiert Decimalanalysieren lassen.

Das GridView-Ereignis RowUpdating akzeptiert als zweiten Parameter ein Objekt vom Typ GridViewUpdateEventArgs, das ein NewValues Wörterbuch als eine seiner Eigenschaften enthält, das die vom Benutzer bereitgestellten Werte enthält, die bereit sind, der ObjectDataSource-Auflistung UpdateParameters zugewiesen zu werden. Wir können den vorhandenen UnitPrice Wert in der Auflistung mit einem Dezimalwert überschreiben, der NewValues mithilfe des Währungsformats mit den folgenden Codezeilen im RowUpdating Ereignishandler analysiert wird:

Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
    Handles GridView1.RowUpdating
    If e.NewValues("UnitPrice") IsNot Nothing Then
        e.NewValues("UnitPrice") = _
            Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
                System.Globalization.NumberStyles.Currency)
    End If
End Sub

Wenn der Benutzer einen UnitPrice Wert angegeben hat (z. B. "$19,00"), wird dieser Wert mit dem dezimalen Wert überschrieben, der von Decimal.Parse berechnet wird, wodurch der Wert als Währung analysiert wird. Dadurch wird das Dezimalzeichen bei Währungssymbolen, Kommas, Dezimalpunkten usw. korrekt analysiert und die NumberStyles-Enumeration im System.Globalization-Namespace verwendet.

Abbildung 11 zeigt sowohl das Problem, das durch Währungssymbole in der vom Benutzer bereitgestellten UnitPriceverursacht wird, als auch, wie der GridView-Ereignishandler RowUpdating verwendet werden kann, um solche Eingaben ordnungsgemäß zu analysieren.

Diagramm, das zeigt, wie objectDataSource das UnitPrice-Feld verarbeitet und wie der RowUpdate-Ereignishandler der GridView eine Zeichenfolge in eine Dezimaldatei konvertiert.

Abbildung 11: Der Wert der UnitPrice bearbeiteten Zeile ist jetzt als Währung formatiert (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Schritt 2: VerbietenNULL UnitPrices

Während die Datenbank so konfiguriert ist, dass Werte in der Spalte der Tabelle zulässig NULL sind, möchten wir möglicherweise verhindern, dass Benutzer, die diese bestimmte Seite besuchen, einen NULLUnitPrice Wert UnitPrice angeben.Products Das heißt, wenn ein Benutzer beim Bearbeiten einer Produktzeile keinen UnitPrice Wert eingeben kann, anstatt die Ergebnisse in der Datenbank zu speichern, möchten wir eine Meldung anzeigen, die den Benutzer darüber informiert, dass über diese Seite für alle bearbeiteten Produkte ein Preis angegeben werden muss.

Das GridViewUpdateEventArgs an den GridView-Ereignishandler RowUpdating übergebene Objekt enthält eine Cancel Eigenschaft, die den Aktualisierungsvorgang beendet, wenn er auf Truefestgelegt ist. Erweitern wir den RowUpdating Ereignishandler auf e.Cancel und zeigt eine Meldung an True , die erklärt, warum der UnitPrice Wert in der NewValues Auflistung den Wert hat Nothing.

Beginnen Sie mit dem Hinzufügen eines Label-Websteuerelements zur Seite mit dem Namen MustProvideUnitPriceMessage. Dieses Label-Steuerelement wird angezeigt, wenn der Benutzer beim Aktualisieren eines Produkts keinen UnitPrice Wert angeben kann. Legen Sie die Eigenschaft des Text Labels auf "Sie müssen einen Preis für das Produkt angeben" fest. Ich habe auch eine neue CSS-Klasse mit Styles.css dem Namen Warning mit der folgenden Definition erstellt:

.Warning
{
    color: Red;
    font-style: italic;
    font-weight: bold;
    font-size: x-large;
}

Legen Sie schließlich die Label-Eigenschaft CssClass auf fest Warning. An diesem Punkt sollte der Designer die Warnmeldung in einem roten, fetten, kursiven und extra großen Schriftgrad über der GridView anzeigen, wie in Abbildung 12 dargestellt.

Über der GridView wurde eine Bezeichnung hinzugefügt.

Abbildung 12: Über der GridView wurde eine Bezeichnung hinzugefügt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Standardmäßig sollte diese Bezeichnung ausgeblendet sein, daher legen Sie die Visible Eigenschaft im Page_Load Ereignishandler auf False fest:

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    MustProvideUnitPriceMessage.Visible = False
End Sub

Wenn der Benutzer versucht, ein Produkt zu aktualisieren, ohne anzugeben UnitPrice, möchten wir das Update abbrechen und die Warnbezeichnung anzeigen. Erweitern Sie den GridView-Ereignishandler RowUpdating wie folgt:

Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
    Handles GridView1.RowUpdating

    If e.NewValues("UnitPrice") IsNot Nothing Then
        e.NewValues("UnitPrice") = _
            Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
                System.Globalization.NumberStyles.Currency)
    Else
        MustProvideUnitPriceMessage.Visible = True

        e.Cancel = True
    End If
End Sub

Wenn ein Benutzer versucht, ein Produkt zu speichern, ohne einen Preis anzugeben, wird das Update abgebrochen, und es wird eine hilfreiche Meldung angezeigt. Während die Datenbank (und die Geschäftslogik) s zulässt NULLUnitPrice , ist dies bei dieser speziellen ASP.NET Seite nicht der Fall.

Ein Benutzer kann UnitPrice nicht leer lassen.

Abbildung 13: Ein Benutzer kann nicht leer lassen UnitPrice (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Bisher haben wir erfahren, wie Sie das GridView-Ereignis RowUpdating verwenden, um die Parameterwerte, die der ObjectDataSource-Auflistung UpdateParameters zugewiesen sind, programmgesteuert zu ändern und den Aktualisierungsprozess vollständig abzubrechen. Diese Konzepte werden auf die Steuerelemente DetailsView und FormView übertragen und gelten auch für das Einfügen und Löschen.

Diese Aufgaben können auch auf ObjectDataSource-Ebene über Ereignishandler für die Insertingereignisse, , Updatingund Deleting ausgeführt werden. Diese Ereignisse werden ausgelöst, bevor die zugeordnete Methode des zugrunde liegenden Objekts aufgerufen wird, und bieten eine möglichkeit, die Eingabeparameterauflistung zu ändern oder den Vorgang direkt abzubrechen. Die Ereignishandler für diese drei Ereignisse werden ein Objekt vom Typ ObjectDataSourceMethodEventArgs übergeben, das über zwei interessante Eigenschaften verfügt:

  • Abbrechen, der den ausgeführten Vorgang abbricht, wenn auf Truefestgelegt ist
  • InputParameters, bei dem es sich um die Auflistung von InsertParameters, UpdateParametersoder DeleteParametershandelt, je nachdem, ob der Ereignishandler für das Inserting- Updatingoder Deleting -Ereignis ist

Um die Arbeit mit den Parameterwerten auf ObjectDataSource-Ebene zu veranschaulichen, fügen wir eine DetailsView auf unserer Seite hinzu, mit der benutzer ein neues Produkt hinzufügen können. Diese DetailsView wird verwendet, um eine Schnittstelle zum schnellen Hinzufügen eines neuen Produkts zur Datenbank bereitzustellen. Um beim Hinzufügen eines neuen Produkts eine konsistente Benutzeroberfläche beizubehalten, erlauben wir dem Benutzer, nur Werte für die ProductName Felder und UnitPrice einzugeben. Standardmäßig werden die Werte, die nicht in der Einfügeschnittstelle von DetailsView angegeben werden, auf einen NULL Datenbankwert festgelegt. Wir können jedoch das ObjectDataSource-Ereignis Inserting verwenden, um verschiedene Standardwerte einzuordnen, wie wir in Kürze sehen werden.

Schritt 3: Bereitstellen einer Schnittstelle zum Hinzufügen neuer Produkte

Ziehen Sie eine DetailsView aus der Toolbox auf die Designer über der GridView, löschen Sie die Height Eigenschaften und Width die Eigenschaften, und binden Sie sie an die ObjectDataSource, die bereits auf der Seite vorhanden ist. Dadurch wird ein BoundField- oder CheckBoxField-Element für jedes Produktfeld hinzugefügt. Da wir diese DetailsView verwenden möchten, um neue Produkte hinzuzufügen, müssen wir die Option Einfügen aktivieren über das Smarttag aktivieren. Es gibt jedoch keine solche Option, da die ObjectDataSource-Methode Insert() keiner Methode in der ProductsBLL -Klasse zugeordnet ist (beachten Sie, dass wir diese Zuordnung beim Konfigurieren der Datenquelle auf (None) festlegen, siehe Abbildung 3).

Wählen Sie zum Konfigurieren der ObjectDataSource den Link Datenquelle konfigurieren aus dem Smarttag aus, und starten Sie den Assistenten. Auf dem ersten Bildschirm können Sie das zugrunde liegende Objekt ändern, an das ObjectDataSource gebunden ist. Lassen Sie sie auf ProductsBLLfestgelegt. Auf dem nächsten Bildschirm werden die Zuordnungen von den ObjectDataSource-Methoden zum zugrunde liegenden Objekt aufgelistet. Obwohl wir explizit darauf hingewiesen haben, dass die Insert() Methoden und Delete() keinen Methoden zugeordnet werden sollten, sehen Sie, wenn Sie zu den Registerkarten INSERT und DELETE wechseln, dass eine Zuordnung vorhanden ist. Dies liegt daran, dass die ProductsBLLMethoden "s AddProduct " und DeleteProduct "s" das DataObjectMethodAttribute -Attribut verwenden, um anzugeben, dass sie die Standardmethoden für Insert() bzw Delete(). sind. Daher wählt der ObjectDataSource-Assistent diese bei jeder Ausführung des Assistenten aus, es sei denn, es ist ein anderer Wert explizit angegeben.

Lassen Sie die Insert() Methode auf die AddProduct -Methode verweisen, aber legen Sie die Dropdownliste der Registerkarte DELETE erneut auf (Keine) fest.

Legen Sie die Drop-Down Liste der Registerkarte INSERT auf die AddProduct-Methode fest.

Abbildung 14: Legen Sie die Drop-Down Liste der Registerkarte INSERT auf die AddProduct -Methode fest (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Legen Sie die Drop-Down Liste der REGISTERKARTE LÖSCHEN auf (Keine) fest.

Abbildung 15: Legen Sie die Drop-Down Liste der REGISTERKARTE LÖSCHEN auf (Keine) fest (Klicken Sie, um das bild in voller Größe anzuzeigen)

Nachdem Sie diese Änderungen vorgenommen haben, wird die deklarative Syntax von ObjectDataSource erweitert, um eine InsertParameters Auflistung einzuschließen, wie unten gezeigt:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
    InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="unitPrice" Type="Decimal" />
        <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>

Durch die erneute Ausführung des Assistenten wurde die OldValuesParameterFormatString Eigenschaft wieder hinzugefügt. Nehmen Sie sich einen Moment Zeit, um diese Eigenschaft zu löschen, indem Sie sie auf den Standardwert ({0}) festlegen oder sie vollständig aus der deklarativen Syntax entfernen.

Da die ObjectDataSource Einfügefunktionen bereitstellt, enthält das Smarttag von DetailsView jetzt das Kontrollkästchen Einfügen aktivieren. kehren Sie zum Designer zurück, und aktivieren Sie diese Option. Analysieren Sie als Nächstes die DetailsView so, dass sie nur über zwei BoundFields - ProductName und UnitPrice - und das CommandField verfügt. An diesem Punkt sollte die deklarative Syntax von DetailsView wie folgt aussehen:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Fields>
        <asp:BoundField DataField="ProductName"
          HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
          SortExpression="UnitPrice" />
        <asp:CommandField ShowInsertButton="True" />
    </Fields>
</asp:DetailsView>

Abbildung 16 zeigt diese Seite, wenn sie an diesem Punkt über einen Browser angezeigt wird. Wie Sie sehen, werden in der DetailsView der Name und der Preis des ersten Produkts (Chai) aufgelistet. Was wir jedoch wollen, ist eine Einfügeschnittstelle, die dem Benutzer eine Möglichkeit bietet, schnell ein neues Produkt zur Datenbank hinzuzufügen.

DetailsView wird derzeit im Read-Only Modus gerendert

Abbildung 16: DetailsView wird derzeit im Read-Only-Modus gerendert (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Um die DetailsView im Einfügemodus anzuzeigen, müssen wir die DefaultMode -Eigenschaft auf Insertingfestlegen. Dadurch wird die DetailsView beim ersten Besuch im Einfügemodus gerendert und nach dem Einfügen eines neuen Datensatzes dort beibehalten. Wie Abbildung 17 zeigt, bietet eine solche DetailsView eine schnelle Schnittstelle zum Hinzufügen eines neuen Datensatzes.

DetailsView bietet eine Schnittstelle zum schnellen Hinzufügen eines neuen Produkts

Abbildung 17: Die Detailansicht stellt eine Schnittstelle zum schnellen Hinzufügen eines neuen Produkts bereit (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Wenn der Benutzer einen Produktnamen und einen Preis eingibt (z. B. "Acme Water" und 1.99, wie in Abbildung 17 dargestellt) und auf Einfügen klickt, erfolgt ein Postback, und der Einfügeworkflow beginnt, der in einem neuen Produktdatensatz gipfelt, der der Datenbank hinzugefügt wird. Die DetailsView behält ihre Einfügeschnittstelle bei, und die GridView wird automatisch an ihre Datenquelle zurückgespeist, um das neue Produkt einzuschließen, wie in Abbildung 18 dargestellt.

Das Produkt

Abbildung 18: Das Produkt "Acme Water" wurde der Datenbank hinzugefügt

Die GridView in Abbildung 18 zeigt dies zwar nicht, aber die Produktfelder, die in der DetailsView-Schnittstelle CategoryIDfehlen, SupplierIDsind QuantityPerUnitdatenbankseitig zugewiesene NULL Werte. Dies können Sie sehen, indem Sie die folgenden Schritte ausführen:

  1. Wechseln Sie zum server-Explorer in Visual Studio.
  2. Erweitern des Datenbankknotens NORTHWND.MDF
  3. Klicken Sie mit der rechten Maustaste auf den Datenbanktabellenknoten Products
  4. Wählen Sie Tabellendaten anzeigen aus.

Dadurch werden alle Datensätze in der Products Tabelle aufgelistet. Wie Abbildung 19 zeigt, weisen NULL alle Spalten unseres neuen Produkts mit Ausnahme ProductIDvon , ProductNameund UnitPrice Werte auf.

Die in der DetailAnsicht nicht bereitgestellten Produktfelder sind zugewiesene NULL-Werte.

Abbildung 19: Die in der Detailansicht nicht bereitgestellten Produktfelder sind zugewiesene NULL Werte (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Möglicherweise möchten wir einen anderen Standardwert als NULL für einen oder mehrere dieser Spaltenwerte angeben, entweder, weil NULL dies nicht die beste Standardoption ist oder weil die Datenbankspalte selbst keines zulässt NULL . Um dies zu erreichen, können wir die Werte der Parameter der DetailView-Auflistung InputParameters programmgesteuert festlegen. Diese Zuweisung kann entweder im Ereignishandler für das DetailView-Ereignis ItemInserting oder im ObjectDataSource-Ereignis Inserting erfolgen. Da wir bereits die Verwendung der Ereignisse vor und nach der Ebene des Datenwebsteuerelements untersucht haben, untersuchen wir dieses Mal die Verwendung der Ereignisse von ObjectDataSource.

Schritt 4: Zuweisen von Werten zu denCategoryIDParametern undSupplierID

Für dieses Tutorial stellen wir uns vor, dass unserer Anwendung beim Hinzufügen eines neuen Produkts über diese Schnittstelle der CategoryID Wert und SupplierID 1 zugewiesen werden sollte. Wie bereits erwähnt, verfügt objectDataSource über ein Paar von Ereignissen vor und nach der Ebene, die während des Datenänderungsprozesses ausgelöst werden. Wenn die Insert() Methode aufgerufen wird, löst die ObjectDataSource zuerst ihr Inserting Ereignis aus, ruft dann die Methode auf, der ihre Insert() Methode zugeordnet wurde, und löst schließlich das Inserted Ereignis aus. Der Inserting Ereignishandler bietet uns eine letzte Möglichkeit, die Eingabeparameter zu optimieren oder den Vorgang direkt abzubrechen.

Hinweis

In einer realen Anwendung möchten Sie wahrscheinlich den Benutzer entweder die Kategorie und den Lieferanten angeben lassen oder diesen Wert basierend auf bestimmten Kriterien oder geschäftslogik auswählen (anstatt blind eine ID von 1 auszuwählen). Unabhängig davon veranschaulicht das Beispiel, wie der Wert eines Eingabeparameters programmgesteuert aus dem Vorebenenereignis des ObjectDataSource-Ereignisses festgelegt wird.

Nehmen Sie sich einen Moment Zeit, um einen Ereignishandler für das ObjectDataSource-Ereignis Inserting zu erstellen. Beachten Sie, dass der zweite Eingabeparameter des Ereignishandlers ein Objekt vom Typ ObjectDataSourceMethodEventArgsist, das über eine -Eigenschaft für den Zugriff auf die Parameters-Auflistung (InputParameters) und eine -Eigenschaft zum Abbrechen des Vorgangs (Cancel) verfügt.

Protected Sub ObjectDataSource1_Inserting _
    (sender As Object, e As ObjectDataSourceMethodEventArgs) _
    Handles ObjectDataSource1.Inserting

End Sub

An diesem Punkt enthält die InputParameters -Eigenschaft die ObjectDataSource-Auflistung InsertParameters mit den Werten, die aus der DetailsView zugewiesen sind. Um den Wert eines dieser Parameter zu ändern, verwenden Sie einfach: e.InputParameters("paramName") = value. Passen Sie daher den CategoryID Ereignishandler so an, dass der Ereignishandler wie folgt aussieht, um und SupplierIDInserting auf den Wert 1 festzulegen:

Protected Sub ObjectDataSource1_Inserting _
    (sender As Object, e As ObjectDataSourceMethodEventArgs) _
    Handles ObjectDataSource1.Inserting

    e.InputParameters("CategoryID") = 1
    e.InputParameters("SupplierID") = 1
End Sub

Wenn Sie ein neues Produkt hinzufügen (z. B. Acme Soda), werden die CategoryID Spalten und SupplierID des neuen Produkts auf 1 festgelegt (siehe Abbildung 20).

Für neue Produkte sind jetzt die CategoryID- und SupplierID-Werte auf 1 festgelegt.

Abbildung 20: Neue Produkte haben ihre CategoryID Werte und SupplierID auf 1 festgelegt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Zusammenfassung

Während des Bearbeitungs-, Einfüge- und Löschvorgangs durchlaufen sowohl das Datenwebsteuerelement als auch die ObjectDataSource eine Reihe von Ereignissen vor und nach der Ebene. In diesem Tutorial haben wir die Ereignisse vor der Ebene untersucht und erfahren, wie Sie diese verwenden, um die Eingabeparameter anzupassen oder den Datenänderungsvorgang vollständig sowohl aus dem Datenwebsteuerelement als auch von ObjectDataSource-Ereignissen abzubrechen. Im nächsten Tutorial sehen wir uns das Erstellen und Verwenden von Ereignishandlern für die Ereignisse nach der Ebene an.

Viel Spaß beim Programmieren!

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderer Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Hauptprüfer für dieses Tutorial waren Jackie Goor und Liz Shulok. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.