Überprüfen von Ereignissen im Zusammenhang mit Vorgängen zum Einfügen, Aktualisieren und Löschen (VB)
von Scott Mitchell
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:
- GridView füllt seine ObjectDataSource
UpdateParameters
mit den eindeutigen identifizierenden Feld(n) des bearbeiteten Datensatzes (über dieDataKeyNames
-Eigenschaft) zusammen mit den vom Benutzer eingegebenen Werten auf. - GridView ruft die ObjectDataSource-Methode auf
Update()
, die wiederum die entsprechende Methode im zugrunde liegenden Objekt aufruft (ProductsDAL.UpdateProduct
in unserem vorherigen Tutorial). - 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 UpdateParameters
hinzuzufü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.
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 undUnitPrice
desProductName
Produkts
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 QuantityPerUnit
UpdateParameters
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 UnitPrice
zu 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
, unitPrice
und 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 ProductID
vorhanden 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.aspx
EditInsertDelete
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 productName
Eingabeparameter , unitPrice
und 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.
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.
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.
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.
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 ProductName
UnitPrice
beschränken. Dies kann erreicht werden, indem die anderen BoundFields und CheckBoxFields entfernt werden, indem die Eigenschaft dieser anderen Felder ReadOnly
auf True
festgelegt 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.
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 false
festlegen, besteht das Risiko, dass gleichzeitige Benutzer datensätze versehentlich löschen oder bearbeiten.
Verbessern derUnitPrice
Formatierung
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 UnitPrice
DataFormatString
BoundField auf {0:c}
und ihre HtmlEncode
-Eigenschaft auf fest False
.
Abbildung 7: Legen Sie die UnitPrice
Eigenschaften 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.
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
.
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.
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 Decimal
analysieren 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 UnitPrice
verursacht wird, als auch, wie der GridView-Ereignishandler RowUpdating
verwendet werden kann, um solche Eingaben ordnungsgemäß zu analysieren.
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 NULL
UnitPrice
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 True
festgelegt 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.
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 NULL
UnitPrice
, ist dies bei dieser speziellen ASP.NET Seite nicht der Fall.
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 Inserting
ereignisse, , Updating
und 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
True
festgelegt ist - InputParameters, bei dem es sich um die Auflistung von
InsertParameters
,UpdateParameters
oderDeleteParameters
handelt, je nachdem, ob der Ereignishandler für dasInserting
-Updating
oderDeleting
-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 ProductsBLL
festgelegt. 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 ProductsBLL
Methoden "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.
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)
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.
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 Inserting
festlegen. 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.
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.
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 CategoryID
fehlen, SupplierID
sind QuantityPerUnit
datenbankseitig zugewiesene NULL
Werte. Dies können Sie sehen, indem Sie die folgenden Schritte ausführen:
- Wechseln Sie zum server-Explorer in Visual Studio.
- Erweitern des Datenbankknotens
NORTHWND.MDF
- Klicken Sie mit der rechten Maustaste auf den Datenbanktabellenknoten
Products
- 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 ProductID
von , ProductName
und UnitPrice
Werte auf.
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 denCategoryID
Parametern 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 ObjectDataSourceMethodEventArgs
ist, 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 SupplierID
Inserting
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).
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.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für