Share via


Hinzufügen von clientseitiger Bestätigung beim Löschen (VB)

von Scott Mitchell

PDF herunterladen

In den schnittstellen, die wir bisher erstellt haben, kann ein Benutzer versehentlich Daten löschen, indem er auf die Schaltfläche Löschen klickt, wenn er auf die Schaltfläche Bearbeiten klicken wollte. In diesem Tutorial fügen Wir ein clientseitiges Bestätigungsdialogfeld hinzu, das angezeigt wird, wenn auf die Schaltfläche Löschen geklickt wird.

Einführung

In den vergangenen Tutorials haben wir erfahren, wie Sie unsere Anwendungsarchitektur, ObjectDataSource und die Datenwebsteuerelemente gemeinsam verwenden, um Funktionen zum Einfügen, Bearbeiten und Löschen bereitzustellen. Die Löschschnittstellen, die wir bisher untersucht haben, bestehen aus einer Löschen-Schaltfläche, die beim Klicken ein Postback auslöst und die ObjectDataSource-Methode Delete() aufruft. Die Delete() -Methode ruft dann die konfigurierte Methode aus der Geschäftslogikebene auf, die den Aufruf an die Datenzugriffsebene weitergibt und die tatsächliche DELETE Anweisung an die Datenbank ausgibt.

Während diese Benutzeroberfläche es Besuchern ermöglicht, Datensätze über die Steuerelemente GridView, DetailsView oder FormView zu löschen, fehlt jede Bestätigung, wenn der Benutzer auf die Schaltfläche Löschen klickt. Wenn ein Benutzer versehentlich auf die Schaltfläche Löschen klickt, wenn er auf Bearbeiten klicken möchte, wird stattdessen der Datensatz gelöscht, den er aktualisieren soll. Um dies zu verhindern, fügen wir in diesem Tutorial ein clientseitiges Bestätigungsdialogfeld hinzu, das angezeigt wird, wenn auf die Schaltfläche Löschen geklickt wird.

Die JavaScript-Funktion confirm(string) zeigt ihren Zeichenfolgeneingabeparameter als Text in einem modalen Dialogfeld an, das mit zwei Schaltflächen ausgestattet ist: OK und Abbrechen (siehe Abbildung 1). Die confirm(string) Funktion gibt einen booleschen Wert zurück, je nachdem, auf welche Schaltfläche geklickt wird (truewenn der Benutzer auf OK klickt und false ob er auf Abbrechen klicken).

Die JavaScript-Methode confirm(string) zeigt ein modales, Client-Side Messagebox an.

Abbildung 1: Die JavaScript-Methode confirm(string) zeigt ein modales, Client-Side Messagebox an.

Wenn während einer Formularübermittlung ein Wert von false von von einem clientseitigen Ereignishandler zurückgegeben wird, wird die Formularübermittlung abgebrochen. Mit diesem Feature können wir den clientseitigen onclick Ereignishandler der Schaltfläche Löschen den Wert eines Aufrufs von zurückgeben confirm("Are you sure you want to delete this product?"). Wenn der Benutzer auf Abbrechen klickt, confirm(string) wird false zurückgegeben, wodurch die Formularübermittlung abgebrochen wird. Ohne Postback wird das Produkt, auf dessen Schaltfläche Löschen geklickt wurde, nicht gelöscht. Wenn der Benutzer jedoch im Bestätigungsdialogfeld auf OK klickt, wird das Postback unvermindert fortgesetzt, und das Produkt wird gelöscht. Weitere Informationen zu diesem Verfahren finden Sie unter Verwenden der JavaScript-Methode confirm() zum Steuern der Formularübermittlung .

Das Hinzufügen des erforderlichen clientseitigen Skripts unterscheidet sich bei Verwendung von Vorlagen geringfügig von der Verwendung eines CommandField. Daher sehen wir uns in diesem Tutorial sowohl ein FormView- als auch ein GridView-Beispiel an.

Hinweis

Bei verwendung clientseitiger Bestätigungstechniken, wie sie in diesem Tutorial erläutert werden, wird davon ausgegangen, dass Ihre Benutzer mit Browsern besuchen, die JavaScript unterstützen und dass JavaScript aktiviert ist. Wenn eine dieser Annahmen für einen bestimmten Benutzer nicht zutrifft, führt das Klicken auf die Schaltfläche Löschen sofort zu einem Postback (es wird kein Bestätigungsmeldungsfeld angezeigt).

Schritt 1: Erstellen einer FormView, die das Löschen unterstützt

Fügen Sie zunächst der Seite im EditInsertDelete Ordner eine FormView ConfirmationOnDelete.aspx hinzu, und binden Sie sie an eine neue ObjectDataSource, die die Produktinformationen über die Methode der ProductsBLL Klasse s GetProducts() zurückzieht. Konfigurieren Sie auch die ObjectDataSource so, dass die Methode der ProductsBLL Klasse s DeleteProduct(productID) der ObjectDataSource-Methode Delete() zugeordnet wird. Stellen Sie sicher, dass die Dropdownlisten INSERT und UPDATE auf (None) festgelegt sind. Aktivieren Sie schließlich das Kontrollkästchen Paging aktivieren im Smarttag von FormView.

Nach diesen Schritten sieht das neue deklarative Markup des ObjectDataSource-Objekts wie folgt aus:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    DeleteMethod="DeleteProduct" OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
    <DeleteParameters>
        <asp:Parameter Name="productID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

Wie in unseren früheren Beispielen, die keine optimistische Parallelität verwendet haben, nehmen Sie sich einen Moment Zeit, um die ObjectDataSource-Eigenschaft OldValuesParameterFormatString zu löschen.

Da es an ein ObjectDataSource-Steuerelement gebunden wurde, das nur das Löschen unterstützt, bietet die FormView s ItemTemplate nur die Schaltfläche Löschen, ohne dass die Schaltflächen Neu und Aktualisieren vorhanden sind. Das deklarative Markup von FormView enthält jedoch ein überflüssiges EditItemTemplate und InsertItemTemplate, das entfernt werden kann. Nehmen Sie sich einen Moment Zeit, um die ItemTemplate anzupassen, sodass nur eine Teilmenge der Produktdatenfelder angezeigt wird. Ich habe meine so konfiguriert, dass der Name des Produkts in einer <h3> Überschrift über den Lieferanten- und Kategorienamen (zusammen mit der Schaltfläche Löschen) angezeigt wird.

<asp:FormView ID="FormView1" AllowPaging="True" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" runat="server">
    <ItemTemplate>
        <h3><i><%# Eval("ProductName") %></i></h3>
        <b>Category:</b>
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Eval("CategoryName") %>'>
        </asp:Label><br />
        <b>Supplier:</b>
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Eval("SupplierName") %>'>
        </asp:Label><br />
        <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
            CommandName="Delete" Text="Delete">
        </asp:LinkButton>
    </ItemTemplate>
</asp:FormView>

Mit diesen Änderungen haben wir eine voll funktionsfähige Webseite, die es einem Benutzer ermöglicht, die Produkte einzeln zu durchlaufen, mit der Möglichkeit, ein Produkt durch einfaches Klicken auf die Schaltfläche Löschen zu löschen. Abbildung 2 zeigt einen Screenshot unseres bisherigen Fortschritts, wenn er über einen Browser angezeigt wird.

Die FormView zeigt Informationen zu einem einzelnen Produkt an.

Abbildung 2: Die FormView zeigt Informationen zu einem einzelnen Produkt an (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Schritt 2: Aufrufen der Funktion confirm(string) über die Schaltflächen löschen Client-Side onclick-Ereignis

Nachdem die FormView erstellt wurde, besteht der letzte Schritt darin, die Schaltfläche Löschen so zu konfigurieren, dass die JavaScript-Funktion confirm(string) aufgerufen wird, wenn der Besucher darauf klickt. Das Hinzufügen clientseitiger Skripts zu einem clientseitigen onclick Button-, LinkButton- oder ImageButton-Ereignis kann durch die Verwendung von OnClientClick propertyerreicht werden, die in ASP.NET 2.0 neu ist. Da der Wert der confirm(string) Funktion zurückgegeben werden soll, legen Sie einfach diese Eigenschaft auf fest: return confirm('Are you certain that you want to delete this product?');

Nach dieser Änderung sollte die deklarative Syntax von LinkButton löschen ungefähr wie folgt aussehen:

<asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
    CommandName="Delete" Text="Delete"
    OnClientClick="return confirm('Are you certain you want to delete this product?');">
</asp:LinkButton>

Das ist alles, was es gibt! Abbildung 3 zeigt einen Screenshot dieser Bestätigung in Aktion. Wenn Sie auf die Schaltfläche Löschen klicken, wird das Dialogfeld Bestätigen angezeigt. Wenn der Benutzer auf Abbrechen klickt, wird das Postback abgebrochen, und das Produkt wird nicht gelöscht. Wenn der Benutzer jedoch auf OK klickt, wird das Postback fortgesetzt, und die ObjectDataSource-Methode Delete() wird aufgerufen, was zum Löschen des Datenbankdatensatzes führt.

Hinweis

Die an die confirm(string) JavaScript-Funktion übergebene Zeichenfolge wird durch Apostrophe (anstelle von Anführungszeichen) getrennt. In JavaScript können Zeichenfolgen mit beiden Zeichen getrennt werden. Hier verwenden wir Apostrophe, damit die Trennzeichen für die übergebene confirm(string) Zeichenfolge keine Mehrdeutigkeit mit den Für den OnClientClick Eigenschaftswert verwendeten Trennzeichen einführen.

Beim Klicken auf die Schaltfläche

Abbildung 3: Beim Klicken auf die Schaltfläche "Löschen" wird jetzt eine Bestätigung angezeigt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Schritt 3: Konfigurieren der OnClientClick-Eigenschaft für die Schaltfläche "Löschen" in einem CommandField

Wenn Sie mit einem Button, LinkButton oder ImageButton direkt in einer Vorlage arbeiten, kann ein Bestätigungsdialogfeld diesem zugeordnet werden, indem sie einfach seine OnClientClick Eigenschaft so konfiguriert, dass die Ergebnisse der JavaScript-Funktion confirm(string) zurückgegeben werden. Das CommandField-Element, das einem GridView- oder DetailView-Steuerelement ein Feld mit Schaltflächen zum Löschen hinzufügt, verfügt jedoch nicht über eine OnClientClick Eigenschaft, die deklarativ festgelegt werden kann. Stattdessen müssen wir programmgesteuert auf die Schaltfläche Löschen im entsprechenden DataBound GridView- oder DetailsView-Ereignishandler verweisen und dann ihre OnClientClick Eigenschaft dort festlegen.

Hinweis

Beim Festlegen der Eigenschaft Schaltfläche löschen OnClientClick im entsprechenden DataBound Ereignishandler haben wir Zugriff auf die Daten, die an den aktuellen Datensatz gebunden wurden. Dies bedeutet, dass wir die Bestätigungsmeldung erweitern können, um Details zum jeweiligen Datensatz zu enthalten, z. B. "Möchten Sie das Chai-Produkt wirklich löschen?" Eine solche Anpassung ist auch in Vorlagen mit Datenbindungssyntax möglich.

Um das Festlegen der OnClientClick Eigenschaft für die Schaltflächen "Löschen" in einem CommandField zu üben, fügen Sie der Seite ein GridView-Element hinzu. Konfigurieren Sie dieses GridView so, dass dasselbe ObjectDataSource-Steuerelement verwendet wird, das von FormView verwendet wird. Beschränken Sie außerdem die BoundFields von GridView auf den Namen, die Kategorie und den Lieferanten des Produkts. Aktivieren Sie abschließend das Kontrollkästchen Löschen aktivieren im Smarttag von GridView. Dadurch wird der GridView-Auflistung Columns ein CommandField hinzugefügt, dessen ShowDeleteButton Eigenschaft auf truefestgelegt ist.

Nachdem Sie diese Änderungen vorgenommen haben, sollte Ihr deklaratives GridView-Markup wie folgt aussehen:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True"
            SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True"
            SortExpression="SupplierName" />
    </Columns>
</asp:GridView>

CommandField enthält eine einzelne Delete LinkButton-instance, auf die programmgesteuert über den GridView-Ereignishandler RowDataBound zugegriffen werden kann. Sobald darauf verwiesen wird, können wir die - OnClientClick Eigenschaft entsprechend festlegen. Erstellen Sie mithilfe des folgenden Codes einen Ereignishandler für das RowDataBound Ereignis:

Protected Sub GridView1_RowDataBound(ByVal sender As Object, _
    ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _
    Handles GridView1.RowDataBound

    If e.Row.RowType = DataControlRowType.DataRow Then
        ' reference the Delete LinkButton
        Dim db As LinkButton = CType(e.Row.Cells(0).Controls(0), LinkButton)

        ' Get information about the product bound to the row
        Dim product As Northwind.ProductsRow = _
            CType(CType(e.Row.DataItem, System.Data.DataRowView).Row, _
            Northwind.ProductsRow)

        db.OnClientClick = String.Format( _
            "return confirm('Are you certain you want to delete the {0} product?');", _
            product.ProductName.Replace("'", "\'"))
    End If
End Sub

Dieser Ereignishandler arbeitet mit Datenzeilen (mit der Schaltfläche Löschen) und verweist programmgesteuert auf die Schaltfläche Löschen. Verwenden Sie im Allgemeinen das folgende Muster:

Dim obj As ButtonType = _
    CType(e.Row.Cells(commandFieldIndex).Controls(controlIndex), ButtonType)

ButtonType ist der Typ der Schaltfläche, die von CommandField - Button, LinkButton oder ImageButton verwendet wird. Standardmäßig verwendet das CommandField LinkButtons, dies kann jedoch über commandField s ButtonType propertyangepasst werden. CommandFieldIndex ist der Ordnungsindex des CommandField innerhalb der GridView-AuflistungColumns, während controlIndex der Index der Schaltfläche Löschen in der CommandField-Auflistung Controls ist. Der controlIndex-Wert hängt von der Position der Schaltfläche relativ zu anderen Schaltflächen im CommandField ab. Wenn beispielsweise die einzige schaltfläche, die im CommandField angezeigt wird, die Schaltfläche Löschen ist, verwenden Sie den Index 0. Wenn jedoch eine Schaltfläche Bearbeiten vorhanden ist, die der Schaltfläche Löschen vorangeht, verwenden Sie einen Index von 2. Der Grund, warum ein Index von 2 verwendet wird, liegt daran, dass vom CommandField vor der Schaltfläche Löschen zwei Steuerelemente hinzugefügt werden: die Schaltfläche Bearbeiten und ein LiteralControl, das verwendet wird, um etwas Platz zwischen den Schaltflächen Bearbeiten und Löschen hinzuzufügen.

Für unser spezielles Beispiel verwendet das CommandField LinkButtons und verfügt als linksstes Feld über einen commandFieldIndex-Wert von 0. Da es keine anderen Schaltflächen außer der Schaltfläche Löschen im CommandField gibt, verwenden wir einen controlIndex von 0.

Nachdem wir auf die Schaltfläche Löschen im CommandField verwiesen haben, greifen wir als nächstes Informationen zum Produkt ab, die an die aktuelle GridView-Zeile gebunden sind. Schließlich legen wir die Eigenschaft Schaltfläche löschen OnClientClick auf das entsprechende JavaScript fest, das den Namen des Produkts enthält. Da die an die confirm(string) Funktion übergebene JavaScript-Zeichenfolge mit Apostrophen getrennt wird, müssen wir alle Apostrophe escapen, die im Namen des Produkts angezeigt werden. Insbesondere werden alle Apostrophe im Produktnamen mit "\'" versehen.

Wenn diese Änderungen abgeschlossen sind, wird beim Klicken auf die Schaltfläche Löschen im GridView-Fenster ein benutzerdefiniertes Bestätigungsdialogfeld angezeigt (siehe Abbildung 4). Wenn der Benutzer auf Abbrechen klickt, wird das Postback wie beim Bestätigungsmeldungsfeld aus der FormView abgebrochen, wodurch das Löschen verhindert wird.

Hinweis

Dieses Verfahren kann auch verwendet werden, um programmgesteuert auf die Schaltfläche Löschen im CommandField in einer DetailsView zuzugreifen. Für die DetailsView erstellen Sie jedoch einen Ereignishandler für das DataBound Ereignis, da die DetailsView kein -Ereignis enthält RowDataBound .

Wenn Sie auf die Schaltfläche

Abbildung 4: Klicken auf die Schaltfläche "Löschen" von GridView zeigt ein benutzerdefiniertes Bestätigungsdialogfeld an (klicken, um das bild in voller Größe anzuzeigen)

Verwenden von TemplateFields

Einer der Nachteile von CommandField besteht darin, dass auf seine Schaltflächen über die Indizierung zugegriffen werden muss und dass das resultierende Objekt in den entsprechenden Schaltflächentyp (Button, LinkButton oder ImageButton) umgewandelt werden muss. Die Verwendung von "magischen Zahlen" und hartcodierten Typen lädt Zu Problemen ein, die bis zur Laufzeit nicht erkannt werden können. Wenn Sie oder ein anderer Entwickler beispielsweise dem CommandField zu einem späteren Zeitpunkt neue Schaltflächen hinzufügen (z. B. eine Schaltfläche Bearbeiten) oder die ButtonType Eigenschaft ändert, wird der vorhandene Code weiterhin ohne Fehler kompiliert, aber der Besuch der Seite kann eine Ausnahme oder unerwartetes Verhalten verursachen, je nachdem, wie Ihr Code geschrieben wurde und welche Änderungen vorgenommen wurden.

Ein alternativer Ansatz besteht darin, die CommandFields von GridView und DetailsView in TemplateFields zu konvertieren. Dadurch wird ein TemplateField mit einem ItemTemplate generiert, das über ein LinkButton (oder Button oder ImageButton) für jede Schaltfläche im CommandField verfügt. Diese Schaltflächeneigenschaften OnClientClick können deklarativ zugewiesen werden, wie wir mit der FormView gesehen haben, oder der Zugriff kann im entsprechenden DataBound Ereignishandler mithilfe des folgenden Musters programmgesteuert erfolgen:

Dim obj As ButtonType = CType(e.Row.FindControl("controlID"), ButtonType)

Dabei ist controlID der Wert der Eigenschaft der Schaltfläche.ID Dieses Muster erfordert zwar weiterhin einen hartcodierten Typ für die Umwandlung, entfällt jedoch die Indizierung, sodass sich das Layout ändern kann, ohne dass es zu einem Laufzeitfehler kommt.

Zusammenfassung

Die JavaScript-Funktion confirm(string) ist eine häufig verwendete Technik zum Steuern des Formularübermittlungsworkflows. Bei Ausführung zeigt die Funktion ein modales, clientseitiges Dialogfeld an, das die beiden Schaltflächen OK und Abbrechen enthält. Wenn der Benutzer auf OK klickt, gibt die confirm(string) Funktion zurück true. Durch Klicken auf Abbrechen wird zurückgegeben false. Diese Funktionalität kann zusammen mit einem Browserverhalten zum Abbrechen einer Formularübermittlung, wenn ein Ereignishandler während des Übermittlungsprozesses zurückgibt false, verwendet werden, um beim Löschen eines Datensatzes ein Bestätigungsmeldungsfeld anzuzeigen.

Die confirm(string) Funktion kann einem clientseitigen onclick Ereignishandler eines Button-Websteuerelements über die Eigenschaft s des Steuerelements OnClientClick zugeordnet werden. Wenn Sie mit einer Schaltfläche Löschen in einer Vorlage arbeiten – entweder in einer der FormView-Vorlagen oder in einem TemplateField in DetailsView oder GridView – kann diese Eigenschaft entweder deklarativ oder programmgesteuert festgelegt werden, wie in diesem Tutorial gezeigt.

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.