Dodawanie potwierdzenia po stronie klienta podczas usuwania (C#)

przez Scott Mitchell

Pobierz przykładową aplikację lub Pobierz plik PDF

W interfejsach, które zostały już utworzone, użytkownik może przypadkowo usunąć dane, klikając przycisk Usuń po kliknięciu przycisku Edytuj. W tym samouczku dodamy okno dialogowe potwierdzenia po stronie klienta, które pojawia się po kliknięciu przycisku Usuń.

Wprowadzenie

W ciągu ostatnich kilku samouczków zaobserwowano, jak korzystać z naszej architektury aplikacji, elementu ObjectDataSource i kontrolek sieci Web danych w ramach uzgodnienia, aby zapewnić możliwość wstawiania, edytowania i usuwania. Usunięte interfejsy, które w tej chwili zostały wykonane, zostały złożone z przycisku usuwania, który po kliknięciu powoduje odświeżenie i wywołanie metody ObjectDataSource s Delete(). Metoda Delete() następnie wywołuje skonfigurowaną metodę z warstwy logiki biznesowej, która propaguje wywołanie do warstwy dostępu do danych, wydając rzeczywistą instrukcję DELETE do bazy danych.

Ten interfejs użytkownika umożliwia osobom odwiedzającym usuwanie rekordów za pomocą kontrolek GridView, DetailsView lub FormView, ale nie ma żadnych potwierdzeń, gdy użytkownik kliknie przycisk Usuń. Jeśli użytkownik przypadkowo kliknie przycisk Usuń, gdy klikniesz przycisk Edytuj, rekord, który ma zostać zaktualizowany, zostanie usunięty. Aby temu zapobiec, w tym samouczku dodamy okno dialogowe potwierdzenia po stronie klienta, które pojawia się po kliknięciu przycisku Usuń.

Funkcja JavaScript confirm(string) wyświetla swój parametr wejściowy ciągu jako tekst wewnątrz modalnego okna dialogowego, które zawiera dwa przyciski — OK i Anuluj (patrz rysunek 1). Funkcja confirm(string) zwraca wartość logiczną w zależności od tego, jaki przycisk jest kliknięty (true, jeśli użytkownik kliknie OK, i false Jeśli kliknie przycisk Anuluj).

Metoda Confirm (String) języka JavaScript wyświetla modalne, po stronie klienta

Rysunek 1. Metoda confirm(string) JavaScript wyświetla modalne, po stronie klienta

W trakcie przekazywania formularza, jeśli wartość false jest zwracana z programu obsługi zdarzeń po stronie klienta, przesyłanie formularza zostanie anulowane. Korzystając z tej funkcji, można użyć przycisku Usuń s po stronie klienta onclick obsługi zdarzeń zwraca wartość wywołania do confirm("Are you sure you want to delete this product?"). Jeśli użytkownik kliknie przycisk Anuluj, confirm(string) zwróci wartość false, co spowoduje anulowanie przesłania formularza. Bez ogłaszania zwrotnego produkt, którego przycisk usuwania został kliknięty, nie zostanie usunięty. Jeśli jednak użytkownik kliknie przycisk OK w oknie dialogowym potwierdzenia, ogłaszanie zwrotne będzie kontynuowane unabated i produkt zostanie usunięty. Aby uzyskać więcej informacji na temat tej techniki, należy zapoznać się z tematem Używanie metody confirm() JavaScript s do sterowania przesyłaniem formularzy .

Dodawanie niezbędnego skryptu po stronie klienta różni się nieco w przypadku używania szablonów niż w przypadku używania CommandField. Dlatego w tym samouczku zobaczymy zarówno widok FormView, jak i widok GridView.

Note

Przy użyciu technik potwierdzeń po stronie klienta, takich jak te omówione w tym samouczku, zakłada się, że użytkownicy odwiedzają przeglądarki obsługujące język JavaScript i obsługujące JavaScript. Jeśli jedno z tych założeń nie jest prawdziwe dla określonego użytkownika, kliknięcie przycisku Usuń spowoduje natychmiastowe zakończenie ogłaszania zwrotnego (bez wyświetlania potwierdzenia MessageBox).

Krok 1. Tworzenie widoku FormView, który obsługuje usuwanie

Zacznij od dodania widoku FormView do strony ConfirmationOnDelete.aspx w folderze EditInsertDelete, aby powiązać ją z nowym elementem ObjectDataSource, który pobiera informacje o produkcie za pomocą metody GetProducts() ProductsBLL Class s. Należy również skonfigurować element ObjectDataSource tak, aby Metoda DeleteProduct(productID) ProductsBLL klasy s została zamapowana na metodę Delete() ObjectDataSource s; Upewnij się, że listy rozwijane kart Wstawianie i aktualizacja są ustawione na wartość (brak). Na koniec zaznacz pole wyboru Włącz stronicowanie w tagu inteligentnym FormView.

Po wykonaniu tych kroków nowe oznakowanie deklaracyjne języka ObjectDataSource będzie wyglądać następująco:

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

Jak w poprzednich przykładach, które nie korzystały z optymistycznej współbieżności, poświęć chwilę na wyczyszczenie właściwości OldValuesParameterFormatString ObjectDataSource s.

Ponieważ został on powiązany z kontrolką ObjectDataSource, która obsługuje tylko usuwanie, tylko ItemTemplate FormView oferuje tylko przycisk Usuń, bez przycisków New i Update. Znaczniki deklaratywne FormView, jednak zawierają zbędne EditItemTemplate i InsertItemTemplate, które mogą zostać usunięte. Poświęć chwilę na dostosowanie ItemTemplate tak, aby pokazywała tylko podzestaw pól danych produktu. Chcę, aby nazwa produktu była wyświetlana w <h3> nagłówku powyżej jego dostawcy i nazwy kategorii (wraz z przyciskiem Usuń).

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

Dzięki tym zmianom mamy w pełni funkcjonalną stronę sieci Web, która umożliwia użytkownikowi jednokrotne przełączanie się między produktami, z możliwością usunięcia produktu przez kliknięcie przycisku Usuń. Rysunek 2 przedstawia zrzut ekranu dotyczący postępu z tego względu, gdy jest wyświetlany za pomocą przeglądarki.

FormView pokazuje informacje o pojedynczym produkcie

Rysunek 2: FormView pokazuje informacje o pojedynczym produkcie (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Krok 2: wywoływanie funkcji Confirm (String) z poziomu zdarzenia onkliknięcia po stronie klienta

Po utworzeniu FormView, ostatnim krokiem jest skonfigurowanie przycisku Usuń, tak aby po kliknięciu jego przez osobę odwiedzającą została wywołana funkcja JavaScript confirm(string). Dodawanie skryptu po stronie klienta do przycisku, element LinkButton lub kliknięto element ImageButton s zdarzenia onclick po stronie klienta można wykonać przy użyciu OnClientClick property, który jest nowy dla ASP.NET 2,0. Ponieważ chcemy mieć wartość zwracaną przez funkcję confirm(string), po prostu ustaw tę właściwość na: return confirm('Are you certain that you want to delete this product?');

Po wprowadzeniu tej zmiany Składnia deklaratywna usuwania element LinkButton powinna wyglądać następująco:

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

Wszystko, co wszystko jest gotowe! Rysunek 3 pokazuje zrzut ekranu przedstawiający to potwierdzenie w akcji. Kliknięcie przycisku Usuń powoduje wyświetlenie okna dialogowego potwierdzenia. Jeśli użytkownik kliknie przycisk Anuluj, ogłaszanie zwrotne zostanie anulowane, a produkt nie zostanie usunięty. Jeśli jednak użytkownik kliknie przycisk OK, ogłaszanie zwrotne będzie kontynuowane, a metoda ObjectDataSource s Delete() zostanie wywołana, culminating w usuwanym rekordzie bazy danych.

Note

Ciąg przesłany do funkcji JavaScript confirm(string) jest rozdzielany znakami apostrofów (a nie cudzysłowów). W języku JavaScript ciągi mogą być rozdzielane przy użyciu dowolnego znaku. W tym miejscu są używane apostrofy, dzięki czemu ograniczniki ciągu przechodzą do confirm(string) nie wprowadzają niejednoznaczności ograniczników używanych dla wartości właściwości OnClientClick.

potwierdzenie jest teraz wyświetlane po kliknięciu przycisku Usuń

Rysunek 3. potwierdzenie jest teraz wyświetlane po kliknięciu przycisku Usuń (kliknij,Aby wyświetlić obraz w pełnym rozmiarze)

Krok 3. Konfigurowanie właściwości OnClientClick przycisku Usuń w CommandField

Podczas pracy z przyciskiem, element LinkButton lub kliknięto element ImageButton bezpośrednio w szablonie, można z nim skojarzyć okno dialogowe potwierdzenia przez skonfigurowanie jego właściwości OnClientClick, aby zwracała wyniki funkcji confirm(string) JavaScript. Jednak CommandField, który dodaje pole usuwania przycisków do widoku GridView lub DetailsView-nie ma właściwości OnClientClick, która może być ustawiona deklaratywnie. Zamiast tego należy programistycznie odwoływać się do przycisku Usuń w obszarze GridView lub DetailsView s odpowiednie DataBound obsługi zdarzeń, a następnie ustawić jego właściwość OnClientClick.

Note

Podczas ustawiania właściwości OnClientClick przycisku Usuń w odpowiedniej procedurze obsługi zdarzeń DataBound, mamy dostęp do danych powiązanych z bieżącym rekordem. Oznacza to, że możemy rozłożyć komunikat potwierdzający, aby uwzględnić szczegóły dotyczące konkretnego rekordu, takiego jak "czy na pewno chcesz usunąć produkt Chai?". Takie dostosowanie jest również możliwe w szablonach przy użyciu składni wiązania danych.

Aby dopuścić do ustawienia właściwości OnClientClick przycisków usuwania w CommandField, Dodaj widok GridView do strony. Skonfiguruj ten widok GridView, aby używał tego samego formantu ObjectDataSource, który jest używany przez FormView. Ogranicz również widok GridView BoundFields, aby zawierał tylko nazwę produktu, kategorię i dostawcę. Na koniec zaznacz pole wyboru Włącz usuwanie w tagu inteligentnym GridView. Spowoduje to dodanie CommandField do kolekcji GridView s Columns z właściwością ShowDeleteButton ustawioną na true.

Po wprowadzeniu tych zmian znaczniki deklaratywne GridView powinny wyglądać następująco:

<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 zawiera pojedyncze wystąpienie klasy Delete element LinkButton, do którego można uzyskać dostęp programowo przy użyciu programu obsługi zdarzeń RowDataBound GridView. Po odwołaniu można ustawić odpowiednio jej Właściwość OnClientClick. Utwórz procedurę obsługi zdarzeń dla zdarzenia RowDataBound przy użyciu następującego kodu:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // reference the Delete LinkButton
        LinkButton db = (LinkButton)e.Row.Cells[0].Controls[0];

        // Get information about the product bound to the row
        Northwind.ProductsRow product =
            (Northwind.ProductsRow) ((System.Data.DataRowView) e.Row.DataItem).Row;

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

Ta procedura obsługi zdarzeń działa z wierszami danych (tymi, które będą miały przycisk Usuń) i rozpoczyna się programowo, odwołując się do przycisku Usuń. Ogólnie rzecz biorąc, użyj następującego wzorca:

ButtonType obj = (ButtonType) e.Row.Cells[commandFieldIndex].Controls[controlIndex];

ButtonType jest typem przycisku używanym przez CommandField-Button, element LinkButton lub kliknięto element ImageButton. Domyślnie CommandField używa LinkButtons, ale można go dostosować za pośrednictwem CommandField s ButtonType property. CommandFieldIndex jest indeksem porządkowym CommandField w kolekcji Columns GridView, podczas gdy controlIndex jest indeksem przycisku usuwania w kolekcji CommandField s Controls. Wartość controlIndex zależy od pozycji przycisku w odniesieniu do innych przycisków w CommandField. Na przykład, jeśli jedynym przyciskiem wyświetlanym w CommandField jest przycisk Usuń, Użyj indeksu 0. Jeśli jednak przycisk Edytuj, który poprzedza przycisk Usuń, Użyj indeksu 2. Przyczyną jest użycie indeksu 2 jest spowodowane tym, że dwie kontrolki są dodawane przez CommandField przed przyciskiem Usuń: przycisk Edytuj i LiteralControl, które służy do dodawania miejsca między przyciskami Edytuj i Usuń.

W naszym konkretnym przykładzie CommandField korzysta z LinkButtons i, że pole z lewej strony ma wartość commandFieldIndex równą 0. Ponieważ nie ma żadnych innych przycisków, ale przycisk Usuń w CommandField, używamy controlIndex 0.

Po odwołaniu się do przycisku Usuń w CommandField następnym zapoznaj się z informacjami o produkcie powiązanym z bieżącym wierszem GridView. Na koniec ustawimy Właściwość OnClientClick przycisku Usuń na odpowiednią JavaScript, która zawiera nazwę produktu. Ponieważ ciąg JavaScript przesłany do funkcji confirm(string) jest rozdzielany przy użyciu apostrofów, musimy wprowadzić wszelkie apostrofy, które pojawiają się w ramach nazwy produktu. W szczególności wszystkie apostrofy w nazwie produktu są oznaczone jako "\'".

Po zakończeniu tych zmian kliknięcie przycisku Usuń w widoku GridView spowoduje wyświetlenie niestandardowego okna dialogowego potwierdzenia (patrz rysunek 4). Podobnie jak w przypadku potwierdzenia MessageBox z widoku FormView, jeśli użytkownik kliknie przycisk Anuluj ogłaszanie zwrotne zostanie anulowane, co uniemożliwi usunięcie.

Note

Tej techniki można również użyć do programistycznego dostępu do przycisku Usuń w CommandField w widoku DetailsView. Dla widoku DetailsView można jednak utworzyć procedurę obsługi zdarzeń dla zdarzenia DataBound, ponieważ w widoku DetailsView nie ma zdarzenia RowDataBound.

kliknięcie przycisku Usuń w widoku GridView powoduje wyświetlenie niestandardowego okna dialogowego potwierdzenia

Ilustracja 4. kliknięcie przycisku Usuń w widoku GridView powoduje wyświetlenie niestandardowego okna dialogowego potwierdzenia (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Korzystanie z używanie TemplateField

Jedną z wad CommandField jest to, że jego przyciski muszą być dostępne za pomocą indeksowania i że obiekt wyniku musi być rzutowany do odpowiedniego typu przycisku (Button, element LinkButton lub kliknięto element ImageButton). Korzystanie z typów "Magic Numbers" i "zakodowanych" zaprasza problemy, których nie można odnaleźć do czasu wykonania. Na przykład, jeśli ty lub inny programista, dodaje nowe przyciski do CommandField w pewnym momencie w przyszłości (na przykład przycisk Edytuj) lub zmienia właściwość ButtonType, istniejący kod nadal będzie kompilować bez błędu, ale odwiedzanie strony może spowodować wyjątek lub nieoczekiwane zachowanie, w zależności od tego, jak zapisano kod i jakie zmiany zostały wprowadzone.

Alternatywnym podejściem jest konwertowanie widoku GridView i widoku DetailsView s CommandFields na używanie TemplateField. Spowoduje to wygenerowanie TemplateField z ItemTemplate, który ma element LinkButton (lub kliknięto element ImageButton) dla każdego przycisku w CommandField. Te przyciski OnClientClick właściwości mogą być przypisywane deklaratywnie, jak w widoku FormView lub można programistycznie uzyskać DataBound do nich dostęp przy użyciu następującego wzorca:

ButtonType obj = (ButtonType) e.Row.FindControl("controlID");

Gdzie controlID jest wartością właściwości ID przycisku. Chociaż ten wzorzec nadal wymaga ustalonego typu dla rzutowania, eliminuje konieczność indeksowania, co pozwala na zmianę układu bez powodu błędu czasu wykonywania.

Podsumowanie

Funkcja JavaScript confirm(string) jest powszechnie stosowaną techniką służącą do sterowania przepływem pracy tworzenia formularzy. Po wykonaniu funkcja wyświetla modalne okno dialogowe po stronie klienta, które zawiera dwa przyciski, OK i Anuluj. Jeśli użytkownik kliknie przycisk OK, funkcja confirm(string) zwróci true; Kliknięcie przycisku Anuluj zwraca false. Ta funkcja, w połączeniu z zachowaniem przeglądarki, umożliwia anulowanie przesłania formularza, jeśli program obsługi zdarzeń w procesie przesłaniania zwróci false, może być używany do wyświetlania elementu MessageBox potwierdzenia podczas usuwania rekordu.

Funkcja confirm(string) może być skojarzona z obsługą zdarzeń onclick po stronie klienta i kontrolki sieci Web na przycisku, korzystając z właściwości Control s OnClientClick. Podczas pracy z przyciskiem Usuń w szablonie — w jednym z szablonów FormView lub w TemplateField w widoku DetailsView lub GridView — tę właściwość można ustawić jako deklaratywną lub programowo, jak pokazano w tym samouczku.

Szczęśliwe programowanie!

Informacje o autorze

Scott Mitchell, autor siedmiu grup ASP/ASP. NET Books i założyciel of 4GuysFromRolla.com, pracował z technologiami sieci Web firmy Microsoft od czasu 1998. Scott działa jako niezależny konsultant, trainer i składnik zapisywania. Jego Najnowsza książka to Sams ASP.NET 2,0 w ciągu 24 godzin. Można go osiągnąć w mitchell@4GuysFromRolla.com. lub za pośrednictwem swojego blogu, który można znaleźć w http://ScottOnWriting.NET.