Überprüfen von Ereignissen im Zusammenhang mit Vorgängen zum Einfügen, Aktualisieren und Löschen (VB)
von Scott Mitchell
In diesem Lernprogramm 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 Bearbeitungsschnittstelle so anpassen, dass nur eine Teilmenge der Produktfelder aktualisiert wird.
Einführung
Bei Verwendung der integrierten Einfüge-, Bearbeitungs- oder Löschfunktionen der GridView-, DetailsView- oder FormView-Steuerelemente wird eine Vielzahl von Schritten transpiriert, wenn der Endbenutzer den Vorgang zum Hinzufügen eines neuen Datensatzes oder aktualisieren oder Löschen eines vorhandenen Datensatzes ausführt. Wie im vorherigen Lernprogramm erläutert, wird die Schaltfläche "Bearbeiten" durch die Schaltfläche "Aktualisieren" und "Abbrechen" ersetzt, wenn eine Zeile in "GridView" bearbeitet wird, und die BoundFields werden in TextBoxes umgewandelt. Nachdem der Endbenutzer die Daten aktualisiert und auf "Aktualisieren" klickt, werden die folgenden Schritte nach dem Postback ausgeführt:
- Das GridView füllt seine ObjectDataSource
UpdateParameters
mit den eindeutigen Identifikationsfeldern des bearbeiteten Datensatzes (über dieDataKeyNames
Eigenschaft) zusammen mit den vom Benutzer eingegebenen Werten auf. - GridView ruft die ObjectDataSource-Methode
Update()
auf, die wiederum die entsprechende Methode im zugrunde liegenden Objekt aufruft (ProductsDAL.UpdateProduct
in unserem vorherigen Lernprogramm) - Die zugrunde liegenden Daten, die jetzt die aktualisierten Änderungen enthalten, werden an gridView rebound to the GridView
In dieser Abfolge von Schritten 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 Überprüfungsfehler auftritt. Wenn die Update()
Methode aufgerufen wird, wird das ObjectDataSource-Ereignis Updating
ausgelöst und bietet die Möglichkeit, die Werte eines der Objekte UpdateParameters
hinzuzufügen oder anzupassen. Nachdem die Methode des zugrunde liegenden Objekts des ObjectDataSource Updated
ausgeführt wurde, wird das Objektereignis ausgelöst. Ein Ereignishandler für das Updated
Ereignis kann die Details zum Aktualisierungsvorgang prüfen, z. B. die Anzahl der betroffenen Zeilen 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 soeben ausgeführten Aktualisierungsvorgang untersuchen.
Abbildung 1 zeigt diese Reihe von Ereignissen und Schritten beim Aktualisieren einer GridView. Das Ereignismuster in Abbildung 1 ist nicht für die Aktualisierung mit einer GridView eindeutig. Durch Einfügen, Aktualisieren oder Löschen von Daten aus gridView, DetailsView oder FormView wird die gleiche Abfolge von Ereignissen vor und nach der Ebene sowohl für das Datenwebsteuerelement als auch für objectDataSource ausgelöst.
Abbildung 1: Eine Reihe von Vor- und Nachereignissen wird ausgelöst, wenn Daten in einer GridView aktualisiert werden (Klicken Sie, um das Bild in voller Größe anzuzeigen)
In diesem Lernprogramm untersuchen wir die Verwendung dieser Ereignisse, um die integrierten Einfüge-, Aktualisierungs- und Löschfunktionen der ASP.NET Datenwebsteuerelemente zu erweitern. Außerdem erfahren Sie, wie Sie die Bearbeitungsschnittstelle so anpassen, dass nur eine Teilmenge der Produktfelder aktualisiert wird.
Schritt 1: Aktualisieren von ProduktProductName
- undUnitPrice
Feldern
In den Bearbeitungsschnittstellen aus dem vorherigen Lernprogramm mussten alle Produktfelder, die nicht schreibgeschützt waren, einbezogen werden. Wenn wir ein Feld aus der GridView entfernen würden , sagen wir QuantityPerUnit
, beim Aktualisieren der Daten würde das Datenwebsteuerelement den Wert von QuantityPerUnit
UpdateParameters
ObjectDataSource nicht festlegen. Die ObjectDataSource würde dann einen Wert der Nothing
UpdateProduct
Business Logic Layer (BLL)-Methode ü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 Bearbeitungsschnittstelle entfernt wird, schlägt die Aktualisierung mit einer Ausnahme vom Typ "Spalte "ProductName" keine NULL-Ausnahme zu. Der Grund für dieses Verhalten war, dass die ObjectDataSource so konfiguriert wurde, dass die Methode der ProductsBLL
Klasse UpdateProduct
aufgerufen wird, die einen Eingabeparameter für die einzelnen Produktfelder erwartet hat. Daher enthielt die ObjectDataSource-Auflistung UpdateParameters
einen Parameter für jeden Eingabeparameter der Methode.
Wenn wir ein Datenwebsteuerelement bereitstellen möchten, mit dem der Endbenutzer nur eine Teilmenge von Feldern aktualisieren kann, müssen wir entweder programmgesteuert die fehlenden UpdateParameters
Werte im Ereignishandler von Updating
ObjectDataSource festlegen oder eine BLL-Methode erstellen und aufrufen, die nur eine Teilmenge der Felder erwartet. Lassen Sie uns diesen ansatz untersuchen.
Insbesondere erstellen wir eine Seite, die nur die ProductName
Felder UnitPrice
in einer bearbeitbaren GridView anzeigt. Über die Bearbeitungsoberfläche von GridView kann der Benutzer nur die beiden angezeigten Felder und die beiden angezeigten Felder ProductName
UnitPrice
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 in ihrem Updating
Ereignishandler festgelegt hat, oder wir müssen eine neue BLL-Methode erstellen, die nur die Teilmenge von Feldern erwartet, die in der GridView definiert sind. In diesem Lernprogramm verwenden wir die letztere Option und erstellen eine Überladung der UpdateProduct
Methode, die nur drei Eingabeparameter einnimmt: 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 überprüft diese Überladung zunächst, ob ein Produkt in der Datenbank mit dem angegebenen Element vorhanden ProductID
ist. Andernfalls wird ein Fehler zurückgegeben False
, der angibt, dass die Anforderung zum Aktualisieren der Produktinformationen fehlgeschlagen ist. Andernfalls aktualisiert sie die vorhandenen Produktdatensätze ProductName
und Felder entsprechend und UnitPrice
führt einen Commit für das Update durch Aufrufen der TableAdapter-Methode Update()
durch Übergeben der ProductsRow
Instanz durch.
Mit dieser Ergänzung zu unserer ProductsBLL
Klasse können wir die vereinfachte GridView-Schnittstelle erstellen. Öffnen Sie den DataModificationEvents.aspx
Ordner, EditInsertDelete
und fügen Sie der Seite eine GridView hinzu. Erstellen Sie eine neue ObjectDataSource, und konfigurieren Sie sie so, dass die Klasse mit der ProductsBLL
Select()
Methodenzuordnung und der Update()
Methodenzuordnung GetProducts
zu der UpdateProduct
Überladung verwendet wird, die nur die productName
Parameter und unitPrice
productID
Eingabeparameter einnimmt. Abbildung 2 zeigt den Assistenten zum Erstellen von Datenquellen, wenn die Methode von ObjectDataSource Update()
der neuen UpdateProduct
Methodenüberladung der ProductsBLL
Klasse zugeordnet wird.
Abbildung 2: Zuordnen der Methode von ObjectDataSource Update()
zur neuen UpdateProduct
Überladung (Klicken, um das Bild in voller Größe anzuzeigen)
Da unser Beispiel zunächst nur die Möglichkeit benötigt, Daten zu bearbeiten, aber keine Datensätze einzufügen oder zu löschen, nehmen Sie sich einen Moment Zeit, um explizit anzugeben, dass die Methoden und Delete()
Methoden von ObjectDataSource Insert()
keiner der Methoden der ProductsBLL
Klasse zugeordnet werden sollten, indem Sie zu den REGISTERKARTEn INSERT und DELETE wechseln und (Keine) aus der Dropdownliste auswählen.
Abbildung 3: Auswählen (Keine) Aus der Dropdownliste für die REGISTERKARTEN EINFÜGEN und LÖSCHEN (Klicken, um das Bild in voller Größe anzuzeigen)
Aktivieren Sie nach Abschluss dieses Assistenten das Kontrollkästchen "Bearbeitung aktivieren" aus dem Smarttag von GridView.
Mit 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 prüfen, das unten dargestellt wird:
<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 es keine Zuordnungen für die ObjectDataSource-Elemente Insert()
und Delete()
-Methoden gibt, gibt es keine InsertParameters
Abschnitte oder DeleteParameters
Abschnitte. Da die Update()
Methode der UpdateProduct
Methodenüberladung zugeordnet ist, die nur drei Eingabeparameter akzeptiert, weist der UpdateParameters
Abschnitt nur drei Parameter
Instanzen auf.
Beachten Sie, dass die ObjectDataSource-Eigenschaft OldValuesParameterFormatString
auf original_{0}
. Diese Eigenschaft wird automatisch von Visual Studio bei Verwendung des Assistenten zum Konfigurieren der Datenquelle festgelegt. 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 OldValuesParameterFormatString
Eigenschaftswert aus dem Eigenschaftenfenster in der Entwurfsansicht löschen, ist die Eigenschaft weiterhin in der deklarativen Syntax vorhanden, wird jedoch auf eine leere Zeichenfolge festgelegt. Entfernen Sie die Eigenschaft entweder vollständig aus der deklarativen Syntax, oder legen Sie den Wert aus dem Eigenschaftenfenster auf den Standardwert fest. {0}
Während die ObjectDataSource nur für den Namen, den Preis und die ID des Produkts verfügt UpdateParameters
, hat Visual Studio für jedes der Felder des Produkts ein BoundField- oder CheckBoxField-Objekt in gridView hinzugefügt.
Abbildung 4: Die GridView enthält ein BoundField- oder CheckBoxField-Element für jedes der Felder des Produkts (Klicken Sie, 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 der Auflistung einen hinzu. Wenn unsere GridView "BoundFields" und "CheckBoxFields" für alle Felder des Produkts enthält, wird die ObjectDataSource daher die UpdateProduct
Überladung aufrufen, die alle diese Parameter einnimmt, obwohl das deklarative Markup von ObjectDataSource nur drei Eingabeparameter angibt (siehe Abbildung 5). Wenn es eine Kombination aus nicht schreibgeschützten Produktfeldern in der GridView gibt, die nicht den Eingabeparametern für eine UpdateProduct
Überladung entsprechen, wird beim Versuch, eine Aktualisierung zu aktualisieren, eine Ausnahme ausgelöst.
Abbildung 5: Die GridView fügt Parameter zur ObjektDatenquelle-Auflistung UpdateParameters
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 einnimmt, müssen wir die GridView auf bearbeitbare Felder nur für das und UnitPrice
die ProductName
. Dies kann erreicht werden, indem die anderen BoundFields und CheckBoxFields entfernt werden, indem Sie die Eigenschaft dieser anderen Felder auf True
oder durch eine Kombination der beiden Felder ReadOnly
festlegen. In diesem Lernprogramm entfernen wir einfach alle GridView-Felder mit Ausnahme der ProductName
" UnitPrice
BoundFields", nach denen das deklarative Markup von GridView wie folgt aussieht:
<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, verfügen wir nur über zwei BoundFields in unserer GridView. 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, UpdateProduct
nur den Namen und den Preis eines Produkts zu bearbeiten, ohne die anderen Produktfelder zu verlieren.
Abbildung 6: Die Benutzeroberfläche 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 Lernprogramm erläutert, ist es wichtig, dass der Ansichtszustand von GridView aktiviert ist (standardverhalten). Wenn Sie die GridView-Eigenschaft auf false
"GridView" EnableViewState
festlegen, besteht das Risiko, dass gleichzeitige Benutzer versehentlich Datensätze löschen oder bearbeiten.
Verbessern derUnitPrice
Formatierung
Obwohl 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. Wenn Sie eine Währungsformatierung für die nicht bearbeitbaren Zeilen anwenden möchten, legen Sie einfach die Eigenschaft von DataFormatString
BoundField auf {0:c}
und deren HtmlEncode
Eigenschaft auf False
.UnitPrice
Abbildung 7: Festlegen der Eigenschaften und ' UnitPrice
s DataFormatString
' HtmlEncode
entsprechend (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Bei 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 angewendet werden, indem sie die Eigenschaft " ApplyFormatInEditMode
BoundField" auf True
"(Standardeinstellung) False
festlegen. Nehmen Sie sich einen Moment Zeit, um diese Eigenschaft auf .True
Abbildung 9: Festlegen der Eigenschaft des UnitPrice
ApplyFormatInEditMode
BoundFields auf True
(Klicken, um das Bild in voller Größe anzuzeigen)
Bei dieser Änderung wird der Wert der UnitPrice
in der bearbeiteten Zeile angezeigten Zeile auch als Währung formatiert.
Abbildung 10: Der Wert der bearbeiteten Zeile UnitPrice
ist jetzt als Währung formatiert (Klicken Sie, um das Bild in voller Größe anzuzeigen)
Beim Aktualisieren eines Produkts mit dem Währungssymbol im Textfeld wie 19,00 $ wird jedoch ein FormatException
. Wenn gridView versucht, die vom Benutzer bereitgestellten Werte der ObjectDataSource-Auflistung UpdateParameters
zuzuweisen, kann die UnitPrice
Zeichenfolge "$19.00" nicht in den Decimal
erforderlichen Parameter konvertiert werden (siehe Abbildung 11). Um dies zu beheben, können wir einen Ereignishandler für das GridView-Ereignis RowUpdating
UnitPrice
erstellen und den vom Benutzer bereitgestellten als währungsformatiert 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, die die vom Benutzer bereitgestellten Werte enthalten, die bereit sind, der ObjectDataSource-Auflistung UpdateParameters
zuzuordnen. Wir können den vorhandenen UnitPrice
Wert in der NewValues
Auflistung mit einem dezimalen Wert überschreiben, der 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 (z. B. "$19,00") angegeben hat, wird dieser Wert mit dem durch Decimal.Parse berechneten Dezimalwert überschrieben, wobei der Wert als Währung analysiert wird. Dadurch wird das Dezimalzeichen korrekt analysiert, wenn Währungssymbole, Kommas, Dezimalkomma usw. vorhanden sind, und die NumberStyles-Aufzählung im System.Globalization-Namespace verwendet wird.
Abbildung 11 zeigt sowohl das Problem, das durch Währungssymbole im vom Benutzer bereitgestellten UnitPrice
Benutzer verursacht wird, als auch, wie der Ereignishandler von RowUpdating
GridView verwendet werden kann, um diese Eingabe korrekt zu analysieren.
Abbildung 11: Der Wert der bearbeiteten Zeile UnitPrice
ist jetzt als Währung formatiert (Klicken Sie, 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, wird eine Meldung angezeigt, in der der Benutzer darüber informiert wird, dass auf dieser Seite alle bearbeiteten Produkte über einen angegebenen Preis verfügen müssen.
Das GridViewUpdateEventArgs
objekt, das an den Ereignishandler von RowUpdating
GridView übergeben wird, enthält eine Cancel
Eigenschaft, die, falls festgelegt, True
den Aktualisierungsprozess beendet. Erweitern wir den RowUpdating
Ereignishandler so, dass er auf True
eine Meldung festgelegt e.Cancel
und angezeigt wird, in der erläutert wird, warum der UnitPrice
Wert in der NewValues
Auflistung einen Wert aufweistNothing
.
Fügen Sie zunächst ein Bezeichnungswebsteuerelement zur Seite mit dem Namen hinzu MustProvideUnitPriceMessage
. Dieses Bezeichnungssteuerelement wird angezeigt, wenn der Benutzer beim Aktualisieren eines Produkts keinen UnitPrice
Wert angeben kann. Legen Sie die Eigenschaft des Etiketts Text
auf "Sie müssen einen Preis für das Produkt angeben". Ich habe auch eine neue CSS-Klasse mit Styles.css
Warning
der folgenden Definition erstellt:
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
Legen Sie schließlich die Eigenschaft der Bezeichnung CssClass
auf Warning
. An diesem Punkt sollte der Designer die Warnmeldung in einer roten, fett formatierten, kursiven, zusätzlichen großen Schriftgröße oberhalb der GridView anzeigen, wie in Abbildung 12 dargestellt.
Abbildung 12: Eine Beschriftung wurde oberhalb der GridView hinzugefügt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Diese Bezeichnung sollte standardmäßig ausgeblendet werden. Legen Sie daher die Visible
Page_Load
Eigenschaft im Ereignishandler festFalse
:
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 ohne Angabe UnitPrice
zu aktualisieren, 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 eine hilfreiche Meldung angezeigt. Während die Datenbank (und Geschäftslogik) s zulässt NULL
UnitPrice
, ist diese bestimmte ASP.NET Seite nicht möglich.
Abbildung 13: Ein Benutzer darf nicht leer lassen UnitPrice
(Klicken, um das Bild in voller Größe anzuzeigen)
Bisher haben wir gesehen, 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 übernehmen die DetailsView- und FormView-Steuerelemente und gelten auch für das Einfügen und Löschen.
Diese Aufgaben können auch auf ObjectDataSource-Ebene über Ereignishandler für die zugehörigen Inserting
Ereignisse Updating
und Deleting
Ereignisse ausgeführt werden. Diese Ereignisse werden ausgelöst, bevor die zugeordnete Methode des zugrunde liegenden Objekts aufgerufen wird, und bieten die Möglichkeit, die Eingabeparameterauflistung zu ändern oder den Vorgang direkt abzubrechen. Die Ereignishandler für diese drei Ereignisse werden an ein Objekt vom Typ ObjectDataSourceMethodEventArgs übergeben, das zwei interessante Eigenschaften aufweist:
- Cancel, which, if set to
True
, cancels the operation being being perform - InputParameters, die die Auflistung von
InsertParameters
, ,UpdateParameters
oderDeleteParameters
, abhängig davon, ob der Ereignishandler für dasInserting
,Updating
, oderDeleting
Ereignis
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 eine konsistente Benutzeroberfläche beim Hinzufügen eines neuen Produkts beizubehalten, erlauben wir es dem Benutzer, nur Werte für die felder und UnitPrice
die ProductName
Werte einzugeben. Standardmäßig werden diese Werte, die nicht in der Einfügeschnittstelle von DetailsView angegeben sind, auf einen NULL
Datenbankwert festgelegt. Wir können jedoch das ObjectDataSource-Ereignis Inserting
verwenden, um unterschiedliche Standardwerte einzuordnen, da wir in Kürze sehen werden.
Schritt 3: Bereitstellen einer Schnittstelle zum Hinzufügen neuer Produkte
Ziehen Sie eine DetailsView aus der Toolbox auf den Designer oberhalb der GridView, löschen Sie die zugehörigen Height
Und Width
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 der Felder des Produkts hinzugefügt. Da wir diese DetailsView zum Hinzufügen neuer Produkte verwenden möchten, müssen wir die Option "Einfügen aktivieren" aus dem Smarttag überprüfen. Es gibt jedoch keine solche Option, da die Methode von Insert()
ObjectDataSource nicht einer Methode in der ProductsBLL
Klasse zugeordnet ist (erinnern Sie sich daran, dass wir diese Zuordnung beim Konfigurieren der Datenquelle auf (Keine) festlegen, siehe Abbildung 3).
Um die ObjectDataSource zu konfigurieren, wählen Sie 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
. Im nächsten Bildschirm werden die Zuordnungen aus den Methoden der ObjectDataSource zu den zugrunde liegenden Objekten aufgelistet. Obwohl wir explizit angegeben haben, dass die Insert()
Methoden und Delete()
Methoden keiner Methode zugeordnet werden sollten, sehen Sie, dass eine Zuordnung vorhanden ist, wenn Sie zu den Registerkarten INSERT und DELETE wechseln. Dies liegt daran, dass die ProductsBLL
's AddProduct
und DeleteProduct
Methoden das DataObjectMethodAttribute
Attribut verwenden, um anzugeben, dass sie die Standardmethoden für Insert()
bzw Delete()
. beide sind. Daher wählt der ObjectDataSource-Assistent diese jedes Mal aus, wenn Sie den Assistenten ausführen, es sei denn, es wird ein anderer Wert explizit angegeben.
Belassen Sie die Methode, die auf die Insert()
AddProduct
Methode zeigt, legen Sie aber erneut die Dropdownliste der DELETE-Registerkarte auf (Keine) fest.
Abbildung 14: Festlegen der Dropdownliste der INSERT-Registerkarte auf die AddProduct
Methode (Klicken, um das Bild in voller Größe anzuzeigen)
Abbildung 15: Festlegen der Dropdownliste der DELETE-Registerkarte auf (Keine) (Klicken, um das Bild in voller Größe anzuzeigen)
Nachdem Sie diese Änderungen vorgenommen haben, wird die deklarative Syntax von ObjectDataSource um eine InsertParameters
Auflistung erweitert, wie unten dargestellt:
<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>
Erneutes Ausführen des Assistenten, der die OldValuesParameterFormatString
Eigenschaft wieder hinzugefügt hat. 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.
Mit der ObjectDataSource, die Einfügefunktionen bereitstellt, enthält das Smarttag von DetailsView nun 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 nur zwei BoundFields - ProductName
und UnitPrice
das CommandField - vorhanden sind. 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 durch einen Browser angezeigt wird. Wie Sie sehen können, listet die DetailsView den Namen und den Preis des ersten Produkts (Chai) auf. Was wir möchten, ist jedoch eine Einfügeschnittstelle, die dem Benutzer eine Möglichkeit bietet, schnell ein neues Produkt zur Datenbank hinzuzufügen.
Abbildung 16: Die Detailansicht wird derzeit im schreibgeschützten Modus gerendert (Klicken Sie hier, 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 in Abbildung 17 dargestellt, bietet eine solche Detailansicht eine schnelle Schnittstelle zum Hinzufügen eines neuen Datensatzes.
Abbildung 17: Die Detailansicht bietet eine Schnittstelle zum schnellen Hinzufügen eines neuen Produkts (Klicken, um das Bild in voller Größe anzuzeigen)
Wenn der Benutzer einen Produktnamen und -preis eingibt (z. B. "Acme Water" und 1,99, wie in Abbildung 17 dargestellt), und klickt auf "Einfügen", beginnt ein Postback und der einzufügende Workflow beginnt, was zu einem neuen Produktdatensatz führt, der der Datenbank hinzugefügt wird. Die DetailsView verwaltet die Einfügeschnittstelle, und GridView wird automatisch an die Datenquelle gebunden, um das neue Produkt einzuschließen, wie in Abbildung 18 dargestellt.
Abbildung 18: Das Produkt "Acme Water" wurde der Datenbank hinzugefügt.
Obwohl die GridView in Abbildung 18 nicht angezeigt wird, werden den Produktfeldern, die von der DetailsView-Schnittstelle CategoryID
fehlen, QuantityPerUnit
SupplierID
usw. Datenbankwerte zugewiesenNULL
. Sie können dies sehen, indem Sie die folgenden Schritte ausführen:
- Wechseln zum Server-Explorer in Visual Studio
- Erweitern des
NORTHWND.MDF
Datenbankknotens - Klicken Sie mit der rechten Maustaste auf den
Products
Datenbanktabellenknoten. - Wählen Sie "Tabellendaten anzeigen" aus.
Dadurch werden alle Datensätze in der Products
Tabelle aufgeführt. Wie in Abbildung 19 dargestellt, sind alle Spalten des neuen Produkts anders als ProductID
, ProductName
und UnitPrice
haben NULL
Werte.
Abbildung 19: Die in der DetailAnsicht nicht bereitgestellten Produktfelder sind zugewiesene NULL
Werte (Klicken Sie, 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 bereitstellen, entweder weil NULL
es sich nicht um die beste Standardoption handelt oder weil die Datenbankspalte selbst dies nicht zulässt NULL
. Dazu können wir die Werte der Parameter der DetailsView-Auflistung InputParameters
programmgesteuert festlegen. Diese Zuweisung kann entweder im Ereignishandler für das Ereignis von ItemInserting
DetailsView oder das ObjectDataSource-Ereignis Inserting
erfolgen. Da wir bereits die Ereignisse vor und nach der Ebene des Datenwebsteuerelements verwendet haben, untersuchen wir dieses Mal die Verwendung der Ereignisse von ObjectDataSource.
Schritt 4: Zuweisen von Werten zu denCategoryID
UndSupplierID
Parametern
In diesem Lernprogramm stellen wir uns vor, dass für unsere Anwendung beim Hinzufügen eines neuen Produkts über diese Schnittstelle ein CategoryID
Wert von 1 zugewiesen SupplierID
werden sollte. Wie bereits erwähnt, weist ObjectDataSource ein Paar ereignisse vor und nach der Ebene auf, die während des Datenänderungsprozesses ausgelöst werden. Wenn die Insert()
Methode aufgerufen wird, löst ObjectDataSource zunächst das Inserting
Ereignis aus, ruft dann die Methode auf, der die Insert()
Methode zugeordnet wurde, und löst schließlich das Inserted
Ereignis aus. Der Inserting
Ereignishandler bietet uns eine letzte Gelegenheit, die Eingabeparameter zu optimieren oder den Vorgang direkt abzubrechen.
Hinweis
In einer realen Anwendung möchten Sie wahrscheinlich entweder zulassen, dass der Benutzer die Kategorie und den Lieferanten angeben oder diesen Wert für sie basierend auf einigen Kriterien oder Geschäftslogik auswählen würde (anstatt blind eine ID von 1 auszuwählen). Unabhängig davon veranschaulicht das Beispiel, wie der Wert eines Eingabeparameters programmgesteuert aus dem Ereignis vor der Ebene von ObjectDataSource 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 Parameterauflistung () und eine Eigenschaft zum Abbrechen des Vorgangs (InputParameters
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 wurden. Um den Wert eines dieser Parameter zu ändern, verwenden Sie einfach Folgendes: e.InputParameters("paramName") = value
. Um die CategoryID
Werte SupplierID
von 1 festzulegen, passen Sie daher den Inserting
Ereignishandler so an, dass er wie folgt aussieht:
Protected Sub ObjectDataSource1_Inserting _
(sender As Object, e As ObjectDataSourceMethodEventArgs) _
Handles ObjectDataSource1.Inserting
e.InputParameters("CategoryID") = 1
e.InputParameters("SupplierID") = 1
End Sub
Dieses Mal werden beim Hinzufügen eines neuen Produkts (z. B. Acme Soda) die CategoryID
Spalten SupplierID
und Spalten des neuen Produkts auf 1 festgelegt (siehe Abbildung 20).
Abbildung 20: Neue Produkte verfügen jetzt über " CategoryID
1" und SupplierID
"Werte" (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Zusammenfassung
Während des Bearbeitungs-, Einfügen- und Löschvorgangs durchlaufen sowohl das Datenwebsteuerelement als auch die ObjectDataSource eine Reihe von Ereignissen vor und nach der Ebene. In diesem Lernprogramm haben wir die Ereignisse vor der Ebene untersucht und gezeigt, wie Sie diese verwenden können, um die Eingabeparameter anzupassen oder den Datenänderungsvorgang vollständig aus den Ereignissen des Datenwebsteuerelements und objectDataSource abzubrechen. Im nächsten Lernprogramm befassen wir uns mit dem Erstellen und Verwenden von Ereignishandlern für die Ereignisse nach der Ebene.
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
Besonderer Dank an
Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüfer für dieses Lernprogramm waren Jackie Goor und Liz Shulok. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn dies der Fall ist, legen Sie mir eine Zeile bei mitchell@4GuysFromRolla.com.