Badanie zdarzeń powiązanych ze wstawianiem, aktualizowaniem i usuwaniem (VB)

Autor: Scott Mitchell

Pobierz plik PDF

W tym samouczku przeanalizujemy użycie zdarzeń, które występują wcześniej, podczas i po operacji wstawiania, aktualizowania lub usuwania kontrolki sieci Web danych ASP.NET. Zobaczymy również, jak dostosować interfejs edycji, aby zaktualizować tylko podzestaw pól produktu.

Wprowadzenie

W przypadku korzystania z wbudowanych funkcji wstawiania, edytowania lub usuwania funkcji kontrolki GridView, DetailsView lub FormView różne kroki są wykonywane, gdy użytkownik końcowy ukończy proces dodawania nowego rekordu lub aktualizowania lub usuwania istniejącego rekordu. Jak omówiono w poprzednim samouczku, gdy wiersz jest edytowany w elemecie GridView, przycisk Edytuj jest zastępowany przez przyciski Aktualizuj i Anuluj, a Pola granic zamieniają się w Pola tekstowe. Po zaktualizowaniu danych przez użytkownika końcowego i kliknięciu pozycji Aktualizuj następujące kroki są wykonywane po powrocie zwrotnym:

  1. Obiekt GridView wypełnia element ObjectDataSource UpdateParameters unikatowymi polami identyfikacji rekordu (za pośrednictwem DataKeyNames właściwości) wraz z wartościami wprowadzonymi przez użytkownika
  2. Obiekt GridView wywołuje metodę ObjectDataSource Update() , która z kolei wywołuje odpowiednią metodę w obiekcie bazowym (ProductsDAL.UpdateProductw poprzednim samouczku)
  3. Dane bazowe, które teraz zawierają zaktualizowane zmiany, są odbicia do kontrolki GridView

Podczas tej sekwencji kroków uruchamiana jest wiele zdarzeń, co umożliwia tworzenie procedur obsługi zdarzeń w celu dodania niestandardowej logiki w razie potrzeby. Na przykład przed krokiem 1 zdarzenie GridView RowUpdating jest uruchamiane. W tym momencie możemy anulować żądanie aktualizacji, jeśli wystąpi błąd weryfikacji. Update() Po wywołaniu metody zdarzenie ObjectDataSource Updating jest wyzwalane, zapewniając możliwość dodania lub dostosowania wartości dowolnego z UpdateParameterselementów . Po zakończeniu wykonywania metody obiektu bazowego obiektu ObjectDataSource zostanie zgłoszone zdarzenie ObjectDataSource Updated . Procedura obsługi zdarzeń Updated dla zdarzenia może sprawdzić szczegóły operacji aktualizacji, takie jak liczba wierszy, których dotyczy problem i czy wystąpił wyjątek. Na koniec, po kroku 2, zdarzenie GridView RowUpdated zostanie wyzwolony. Program obsługi zdarzeń dla tego zdarzenia może sprawdzić dodatkowe informacje o operacji aktualizacji właśnie wykonane.

Rysunek 1 przedstawia tę serię zdarzeń i kroków podczas aktualizowania elementu GridView. Wzorzec zdarzenia na rysunku 1 nie jest unikatowy do aktualizowania za pomocą kontrolki GridView. Wstawianie, aktualizowanie lub usuwanie danych z kontrolki GridView, DetailsView lub FormView powoduje, że ta sama sekwencja zdarzeń wstępnych i po poziomie zarówno dla kontrolki sieci Web danych, jak i obiektu ObjectDataSource.

Seria wyzwalanych zdarzeń wstępnych i po zdarzeniach podczas aktualizowania danych w siatceView

Rysunek 1. Seria wyzwalanych zdarzeń wstępnych i po zdarzeń podczas aktualizowania danych w siatceView (kliknij, aby wyświetlić obraz pełnowymiarowy)

W tym samouczku przeanalizujemy użycie tych zdarzeń, aby rozszerzyć wbudowane funkcje wstawiania, aktualizowania i usuwania kontrolek sieci Web danych ASP.NET. Zobaczymy również, jak dostosować interfejs edycji, aby zaktualizować tylko podzestaw pól produktu.

Krok 1. Aktualizowanie pól iUnitPriceproduktówProductName

W interfejsach edycji z poprzedniego samouczka wszystkie pola produktów, które nie były tylko do odczytu, musiały zostać uwzględnione. Gdybyśmy usunęli pole z kontrolki GridView — powiedzmy QuantityPerUnit — podczas aktualizowania danych kontrolka sieci Web danych nie ustawiłaby wartości ObjectDataSource QuantityPerUnitUpdateParameters . Następnie obiekt ObjectDataSource przekaże wartość Nothing do UpdateProduct metody warstwy logiki biznesowej (BLL), co spowoduje zmianę NULL kolumny QuantityPerUnit edytowanego rekordu bazy danych na wartość. Podobnie, jeśli wymagane pole, takie jak ProductName, zostanie usunięte z interfejsu edycji, aktualizacja zakończy się niepowodzeniem z wyjątkiem "Kolumna "ProductName" nie zezwala na wartości null. Przyczyną tego zachowania było to, że obiekt ObjectDataSource został skonfigurowany do wywołania ProductsBLL metody klasy UpdateProduct , która oczekiwała parametru wejściowego dla każdego pola produktu. W związku z tym kolekcja ObjectDataSource UpdateParameters zawierała parametr dla każdego parametru wejściowego metody.

Jeśli chcemy podać kontrolkę sieci Web danych, która umożliwia użytkownikowi końcowemu aktualizowanie tylko podzestawu pól, musimy programowo ustawić brakujące UpdateParameters wartości w procedurze obsługi zdarzeń objectDataSource Updating lub utworzyć i wywołać metodę BLL, która oczekuje tylko podzestawu pól. Przyjrzyjmy się temu drugiemu podejściu.

W szczególności utwórzmy stronę, która wyświetla tylko ProductName pola i UnitPrice w edytowalnym elemecie GridView. Ten interfejs edycji elementu GridView umożliwi użytkownikowi tylko zaktualizowanie dwóch wyświetlanych pól i ProductNameUnitPrice. Ponieważ ten interfejs edycji udostępnia tylko podzbiór pól produktu, musimy utworzyć obiekt ObjectDataSource, który używa istniejącej metody BLL i ma brakujące wartości pól produktu ustawione programowo w procedurze Updating obsługi zdarzeń, lub musimy utworzyć nową metodę BLLUpdateProduct, która oczekuje tylko podzestawu pól zdefiniowanych w siatce. Na potrzeby tego samouczka użyjemy tej drugiej opcji i utwórzmy przeciążenie UpdateProduct metody , która przyjmuje tylko trzy parametry wejściowe: productName, unitPricei 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

Podobnie jak w przypadku oryginalnej UpdateProduct metody, to przeciążenie rozpoczyna się od sprawdzenia, czy w bazie danych znajduje się produkt o określonej nazwie ProductID. Jeśli nie, zwraca Falsewartość , wskazując, że żądanie aktualizacji informacji o produkcie nie powiodło się. W przeciwnym razie aktualizuje odpowiednio pola i UnitPrice rekordu istniejącego produktu ProductName oraz zatwierdza aktualizację, wywołując metodę TableAdapterUpdate(), przekazując ProductsRow wystąpienie.

Oprócz naszej ProductsBLL klasy jesteśmy gotowi do utworzenia uproszczonego interfejsu GridView. Otwórz folder DataModificationEvents.aspx w folderze EditInsertDelete i dodaj element GridView do strony. Utwórz nowy obiekt ObjectDataSource i skonfiguruj go do użycia ProductsBLL klasy z mapowaniem Select() metody na GetProducts i mapowanie Update() metody na UpdateProduct przeciążenie, które przyjmuje tylko productNameparametry , unitPricei productID wejściowe. Rysunek 2 przedstawia kreatora tworzenia źródła danych podczas mapowania metody ObjectDataSource Update() na ProductsBLL przeciążenie nowej UpdateProduct metody klasy.

Mapowanie metody Update() obiektu ObjectDataSource na przeciążenie new UpdateProduct

Rysunek 2. Mapowanie metody ObjectDataSource Update() na nowe UpdateProduct przeciążenie (kliknij, aby wyświetlić obraz pełnowymiarowy)

Ponieważ nasz przykład początkowo będzie wymagał tylko możliwości edytowania danych, ale nie wstawiania ani usuwania rekordów, poświęć chwilę, aby jawnie wskazać, że metody i objectDataSource Insert()Delete() nie powinny być mapowane na żadne ProductsBLL metody klasy, przechodząc do kart INSERT i DELETE i wybierając pozycję (Brak) z listy rozwijanej.

Wybierz pozycję (Brak) z listy Drop-Down dla kart INSERT i DELETE

Rysunek 3. Wybierz pozycję (Brak) Z listy Drop-Down dla kart INSERT i DELETE (Kliknij, aby wyświetlić obraz pełnowymiarowy)

Po ukończeniu pracy tego kreatora zaznacz pole wyboru Włącz edytowanie z tagu inteligentnego GridView.

Po ukończeniu kreatora Tworzenia źródła danych i powiązaniu go z obiektem GridView program Visual Studio utworzył składnię deklaratywną dla obu kontrolek. Przejdź do widoku Źródło, aby sprawdzić deklaratywne znaczniki objectDataSource, które przedstawiono poniżej:

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

Ponieważ nie ma mapowań dla metod i objectDataSourceInsert(), nie InsertParameters ma żadnych sekcji aniDeleteParameters.Delete() Ponadto, ponieważ Update() metoda jest mapowana na UpdateProduct przeciążenie metody, które akceptuje tylko trzy parametry wejściowe, UpdateParameters sekcja ma tylko trzy Parameter wystąpienia.

Należy pamiętać, że właściwość ObjectDataSource jest ustawiona OldValuesParameterFormatString na original_{0}. Ta właściwość jest ustawiana automatycznie przez program Visual Studio podczas korzystania z Kreatora konfigurowania źródła danych. Jednak ponieważ nasze metody BLL nie oczekują przekazania oryginalnej ProductID wartości, usuń to przypisanie właściwości całkowicie ze składni deklaratywnej obiektu ObjectDataSource.

Uwaga

Jeśli po prostu wyczyścisz OldValuesParameterFormatString wartość właściwości z okno Właściwości w widoku Projekt, właściwość nadal będzie istnieć w składni deklaratywnej, ale zostanie ustawiona na pusty ciąg. Całkowicie usuń właściwość ze składni deklaratywnej lub z okno Właściwości ustaw wartość na wartość domyślną {0}.

Obiekt ObjectDataSource ma UpdateParameters tylko nazwę, cenę i identyfikator produktu, ale program Visual Studio dodał pole BoundField lub CheckBoxField w elemecie GridView dla każdego pola produktu.

Obiekt GridView zawiera pole ograniczenia lub pole wyboru dla każdego pola produktu

Rysunek 4. Obiekt GridView zawiera pole ograniczenia lub pole checkbox dla każdego pola produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Gdy użytkownik końcowy edytuje produkt i kliknie przycisk Aktualizuj, funkcja GridView wylicza te pola, które nie były tylko do odczytu. Następnie ustawia wartość odpowiedniego parametru w kolekcji ObjectDataSource UpdateParameters na wartość wprowadzoną przez użytkownika. Jeśli nie ma odpowiedniego parametru, element GridView dodaje jeden do kolekcji. W związku z tym jeśli element GridView zawiera pola BoundFields i CheckBoxFields dla wszystkich pól produktu, obiekt ObjectDataSource wywoła przeciążenie, które przyjmuje UpdateProduct wszystkie te parametry, pomimo faktu, że deklaratywny znacznik objectDataSource określa tylko trzy parametry wejściowe (patrz Rysunek 5). Podobnie, jeśli w elemecie GridView istnieje kilka kombinacji pól produktu tylko do odczytu, które nie odpowiadają parametrom wejściowym UpdateProduct przeciążenia, podczas próby aktualizacji zostanie zgłoszony wyjątek.

Obiekt GridView doda parametry do kolekcji UpdateParameters elementu ObjectDataSource

Rysunek 5. Widok GridView doda parametry do kolekcji ObjectDataSource UpdateParameters (kliknij, aby wyświetlić obraz pełnowymiarowy)

Aby upewnić się, że obiekt ObjectDataSource wywołuje UpdateProduct przeciążenie, które przyjmuje tylko nazwę, cenę i identyfikator produktu, musimy ograniczyć element GridView do edytowania pól tylko ProductName dla elementów i UnitPrice. Można to osiągnąć przez usunięcie innych pól BoundFields i CheckBoxFields, ustawiając właściwość tych innych pól ReadOnly na True, lub przez kombinację tych dwóch pól. W tym samouczku po prostu usuńmy wszystkie pola GridView z wyjątkiem pól ProductName i UnitPrice BoundFields, po których znacznik deklaratywny kontrolki GridView będzie wyglądać następująco:

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

Mimo że UpdateProduct przeciążenie oczekuje trzech parametrów wejściowych, w siatce GridView mamy tylko dwie wartości BoundFields. Jest to spowodowane tym, że productID parametr wejściowy jest wartością klucza podstawowego i przekazywany przez wartość DataKeyNames właściwości dla edytowanego wiersza.

Nasz element GridView wraz z UpdateProduct przeciążeniem umożliwia użytkownikowi edytowanie tylko nazwy i ceny produktu bez utraty żadnego z innych pól produktu.

Interfejs umożliwia edytowanie tylko nazwy i ceny produktu

Rysunek 6. Interfejs umożliwia edytowanie tylko nazwy i ceny produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Jak wspomniano w poprzednim samouczku, ważne jest, aby stan widoku GridView był włączony (zachowanie domyślne). Jeśli ustawisz właściwość GridView na EnableViewStatefalsewartość , wystąpi ryzyko przypadkowego usunięcia lub edytowania rekordów współbieżnych użytkowników.

PoprawianieUnitPriceformatowania

Chociaż przykład GridView pokazany na rysunku 6 działa, UnitPrice pole nie jest w ogóle sformatowane, co powoduje wyświetlenie ceny, która nie zawiera żadnych symboli waluty i ma cztery miejsca dziesiętne. Aby zastosować formatowanie waluty dla wierszy nieedytowalnych, po prostu ustaw UnitPrice właściwość BoundField DataFormatString na {0:c} i jej HtmlEncode właściwość na False.

Ustaw odpowiednio właściwości DataFormatString i HtmlEncode elementu UnitPrice

Rysunek 7. Ustaw UnitPriceDataFormatString odpowiednio wartości i HtmlEncode właściwości (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Dzięki tej zmianie nieedytowalne wiersze formatują cenę jako walutę; edytowany wiersz nadal wyświetla jednak wartość bez symbolu waluty i z czterema miejscami dziesiętnymi.

Wiersze niezmodytowalne są teraz sformatowane jako wartości waluty

Rysunek 8. Wiersze nieedytowalne są teraz sformatowane jako wartości waluty (kliknij, aby wyświetlić obraz pełnowymiarowy)

Instrukcje formatowania określone we DataFormatString właściwości można zastosować do interfejsu edycji, ustawiając właściwość BoundField ApplyFormatInEditMode na True wartość (wartość domyślna to False). Poświęć chwilę, aby ustawić tę właściwość na True.

Ustaw właściwość ApplyFormatInEditMode elementu UnitPrice BoundField na wartość True

Rysunek 9. Ustaw UnitPrice właściwość BoundField ApplyFormatInEditMode na True (kliknij, aby wyświetlić obraz pełnowymiarowy)

Dzięki tej zmianie wartość UnitPrice wyświetlana w edytowanym wierszu jest również sformatowana jako waluta.

Zrzut ekranu przedstawiający wartość UnitPrice edytowanego wiersza sformatowaną jako waluta.

Rysunek 10. Edytowana wartość wiersza UnitPrice jest teraz sformatowana jako waluta (kliknij, aby wyświetlić obraz pełnowymiarowy)

Jednak zaktualizowanie produktu z symbolem waluty w polu tekstowym, takim jak 19,00 USD, zgłasza błąd FormatException. Gdy obiekt GridView próbuje przypisać wartości dostarczone przez użytkownika do kolekcji ObjectDataSource UpdateParameters , nie może przekonwertować UnitPrice ciągu "$19.00" na Decimal wymagany przez parametr (patrz Rysunek 11). Aby rozwiązać ten problem, możemy utworzyć procedurę obsługi zdarzeń dla zdarzenia GridView RowUpdating i przeanalizować podane UnitPrice przez użytkownika jako walutę sformatowaną Decimal.

Zdarzenie GridView RowUpdating przyjmuje jako drugi parametr obiektu typu GridViewUpdateEventArgs, który zawiera NewValues słownik jako jedną z jego właściwości, które przechowują wartości dostarczone przez użytkownika gotowe do przypisania do kolekcji ObjectDataSource UpdateParameters . Istniejącą UnitPrice wartość w NewValues kolekcji można zastąpić analizą wartości dziesiętnej przy użyciu formatu waluty z następującymi wierszami kodu w procedurze RowUpdating obsługi zdarzeń:

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

Jeśli użytkownik podał UnitPrice wartość (na przykład "$19.00"), ta wartość jest zastępowana wartością dziesiętną obliczoną przez wartość Dziesiętną.Parse, analizowanie wartości jako waluty. Spowoduje to poprawne przeanalizowanie liczby dziesiętnej w przypadku wszystkich symboli walutowych, przecinków, punktów dziesiętnych itd., a także użycie wyliczenia NumberStyles w przestrzeni nazw System.Globalization .

Rysunek 11 przedstawia oba problemy spowodowane symbolami walutowymi w dostarczonym UnitPriceprzez użytkownika element , a także sposób, w jaki program obsługi zdarzeń usługi GridView RowUpdating może być używany do poprawnego analizowania takich danych wejściowych.

Diagram przedstawiający sposób przetwarzania pola UnitPrice przez obiekt ObjectDataSource oraz sposób, w jaki program obsługi zdarzeń RowUpdate elementu GridView konwertuje ciąg na dziesiętny.

Rysunek 11. Edytowana wartość wiersza UnitPrice jest teraz sformatowana jako waluta (kliknij, aby wyświetlić obraz pełnowymiarowy)

Krok 2. ZakazNULL UnitPrices

Chociaż baza danych jest skonfigurowana tak, aby zezwalała na NULL wartości w Products kolumnie tabeli UnitPrice , możemy uniemożliwić użytkownikom odwiedzającym tę konkretną NULLUnitPrice stronę określenie wartości. Oznacza to, że jeśli użytkownik nie wprowadzi UnitPrice wartości podczas edytowania wiersza produktu, zamiast zapisywać wyniki w bazie danych, chcemy wyświetlić komunikat informujący użytkownika, że na tej stronie wszystkie edytowane produkty muszą mieć określoną cenę.

GridViewUpdateEventArgs Obiekt przekazany do programu obsługi zdarzeń GridView RowUpdating zawiera Cancel właściwość, która, jeśli ustawiono wartość True, kończy proces aktualizacji. Rozszerzmy procedurę RowUpdating obsługi zdarzeń, aby ustawić True wartość na e.Cancel i wyświetlić komunikat wyjaśniający, dlaczego UnitPrice wartość w NewValues kolekcji ma wartość Nothing.

Zacznij od dodania kontrolki Etykieta sieci Web do strony o nazwie MustProvideUnitPriceMessage. Ta kontrolka Etykieta zostanie wyświetlona, jeśli użytkownik nie określi UnitPrice wartości podczas aktualizowania produktu. Ustaw właściwość Label Text na "Musisz podać cenę produktu". Utworzono również nową klasę CSS o Styles.css nazwie Warning o następującej definicji:

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

Na koniec ustaw właściwość Label CssClass na Warning. W tym momencie Projektant powinien pokazać komunikat ostrzegawczy w kolorze czerwonym, pogrubionym, kursywą, dodatkowym dużym rozmiarem czcionki powyżej kontrolki GridView, jak pokazano na rysunku 12.

Etykieta została dodana powyżej kontrolki GridView

Rysunek 12. Etykieta została dodana powyżej widoku GridView (kliknij, aby wyświetlić obraz pełnowymiarowy)

Domyślnie ta etykieta powinna być ukryta, więc ustaw jej Visible właściwość na False w programie obsługi zdarzeń Page_Load :

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

Jeśli użytkownik próbuje zaktualizować produkt bez określenia UnitPricewartości , chcemy anulować aktualizację i wyświetlić etykietę ostrzeżenia. Rozszerz procedurę obsługi zdarzeń usługi GridView RowUpdating w następujący sposób:

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

Jeśli użytkownik próbuje zapisać produkt bez określenia ceny, aktualizacja zostanie anulowana i zostanie wyświetlony pomocny komunikat. Chociaż baza danych (i logika biznesowa) zezwala na NULLUnitPrice s, ta konkretna strona ASP.NET nie.

Użytkownik nie może pozostawić pustej wartości unitPrice

Rysunek 13. Użytkownik nie może pozostawić UnitPrice pustego (kliknij, aby wyświetlić obraz pełnowymiarowy)

Do tej pory widzieliśmy, jak za pomocą zdarzenia GridView RowUpdating programowo zmienić wartości parametrów przypisanych do kolekcji ObjectDataSource UpdateParameters , a także jak całkowicie anulować proces aktualizacji. Te pojęcia są przenoszone do kontrolek DetailsView i FormView, a także do wstawiania i usuwania.

Te zadania można również wykonywać na poziomie ObjectDataSource za pomocą procedur obsługi zdarzeń dla zdarzeń Inserting, Updatingi Deleting zdarzeń. Te zdarzenia są uruchamiane przed wywołaną skojarzoną metodą obiektu bazowego i zapewniają możliwość ostatniej szansy na zmodyfikowanie kolekcji parametrów wejściowych lub anulowanie operacji wprost. Procedury obsługi zdarzeń dla tych trzech zdarzeń są przekazywane obiekt typu ObjectDataSourceMethodEventArgs , który ma dwie właściwości zainteresowania:

  • Anuluj, co w przypadku ustawienia na Truewartość , anuluje wykonywaną operację
  • InputParameters, czyli kolekcja InsertParameters, UpdateParameterslub DeleteParameters, w zależności od tego, czy program obsługi zdarzeń jest przeznaczony dla Insertingzdarzenia , lub UpdatingDeleting

Aby zilustrować pracę z wartościami parametrów na poziomie ObjectDataSource, dołączmy element DetailsView na naszej stronie, który umożliwia użytkownikom dodawanie nowego produktu. Ten element DetailsView będzie używany do zapewnienia interfejsu do szybkiego dodawania nowego produktu do bazy danych. Aby zachować spójny interfejs użytkownika podczas dodawania nowego produktu, pozwól użytkownikowi na wprowadzanie tylko wartości dla ProductName pól i UnitPrice . Domyślnie te wartości, które nie są podane w interfejsie wstawiania elementu DetailsView, zostaną ustawione na NULL wartość bazy danych. Jednak możemy użyć zdarzenia ObjectDataSource Inserting do wstrzykiwania różnych wartości domyślnych, jak zobaczymy wkrótce.

Krok 3. Udostępnianie interfejsu w celu dodania nowych produktów

Przeciągnij kontrolkę DetailsView z przybornika na Projektant nad kontrolką GridView, wyczyść jej Height właściwości i Width powiąż ją z obiektem ObjectDataSource już obecnym na stronie. Spowoduje to dodanie pola BoundField lub CheckBoxField dla każdego pola produktu. Ponieważ chcemy użyć tego elementu DetailsView w celu dodania nowych produktów, musimy sprawdzić opcję Włącz wstawianie z tagu inteligentnego; Nie ma jednak takiej opcji, ponieważ metoda ObjectDataSource Insert() nie jest mapowana na metodę w ProductsBLL klasie (przypomnij sobie, że to mapowanie jest ustawione na (Brak) podczas konfigurowania źródła danych zobacz Rysunek 3).

Aby skonfigurować obiekt ObjectDataSource, wybierz link Konfiguruj źródło danych z tagu inteligentnego, uruchamiając kreatora. Pierwszy ekran umożliwia zmianę obiektu bazowego, do którego jest powiązana wartość ObjectDataSource; pozostaw dla niego wartość ProductsBLL. Następny ekran zawiera listę mapowań z metod ObjectDataSource do obiektu bazowego. Mimo że jawnie wskazaliśmy, że Insert() metody i Delete() nie powinny być mapowane na żadne metody, jeśli przejdziesz do kart INSERT i DELETE, zobaczysz, że istnieje mapowanie. Dzieje się tak, ponieważ ProductsBLLAddProduct metody i DeleteProduct używają atrybutu DataObjectMethodAttribute , aby wskazać, że są to odpowiednio metody domyślne dla Insert() i Delete(). W związku z tym kreator ObjectDataSource wybiera je za każdym razem, gdy zostanie uruchomiony kreator, chyba że zostanie określona inna wartość.

Pozostaw metodę Insert() wskazującą metodę AddProduct , ale ponownie ustaw listę rozwijaną karty DELETE na wartość (Brak).

Ustaw listę Drop-Down tabulatora INSERT na metodę AddProduct

Rysunek 14. Ustaw listę Drop-Down tabulatora INSERT na metodę AddProduct (kliknij, aby wyświetlić obraz pełnowymiarowy)

Ustaw listę Drop-Down karty DELETE na (Brak)

Rysunek 15. Ustaw listę Drop-Down karty DELETE na (Brak) (Kliknij, aby wyświetlić obraz pełnowymiarowy)

Po wprowadzeniu tych zmian składnia deklaratywna objectDataSource zostanie rozszerzona, aby uwzględnić InsertParameters kolekcję, jak pokazano poniżej:

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

Ponowne uruchamianie kreatora dodano OldValuesParameterFormatString ponownie właściwość . Poświęć chwilę, aby wyczyścić tę właściwość, ustawiając ją na wartość domyślną ({0}) lub całkowicie usuwając ją ze składni deklaratywnej.

Gdy obiekt ObjectDataSource zapewnia możliwości wstawiania, tag inteligentny Elementu DetailsView będzie teraz zawierać pole wyboru Włącz wstawianie; wróć do Projektant i zaznacz tę opcję. Następnie przeanalizuj widok DetailsView tak, aby miał tylko dwa pola boundfields — ProductName i — i UnitPrice CommandField. W tym momencie składnia deklaratywna elementu DetailsView powinna wyglądać następująco:

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

Rysunek 16 przedstawia tę stronę podczas przeglądania przeglądarki w tym momencie. Jak widać, element DetailsView wyświetla nazwę i cenę pierwszego produktu (Chai). Chcemy jednak wstawić interfejs, który umożliwia użytkownikowi szybkie dodanie nowego produktu do bazy danych.

Element DetailsView jest obecnie renderowany w trybie Read-Only

Rysunek 16. Widok Szczegółów jest obecnie renderowany w trybie Read-Only (kliknij, aby wyświetlić obraz pełnowymiarowy)

Aby wyświetlić element DetailsView w trybie wstawiania, musimy ustawić DefaultMode właściwość na Inserting. Spowoduje to renderowanie elementu DetailsView w trybie wstawiania po pierwszym odwiedzeniu i utrzymuje go tam po wstawieniu nowego rekordu. Jak pokazano na rysunku 17, taki element DetailsView zapewnia szybki interfejs dodawania nowego rekordu.

Element DetailsView udostępnia interfejs do szybkiego dodawania nowego produktu

Rysunek 17. Widok Szczegółów zawiera interfejs umożliwiający szybkie dodawanie nowego produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Gdy użytkownik wprowadzi nazwę i cenę produktu (na przykład "Acme Water" i 1,99, jak na rysunku 17), a następnie kliknie pozycję Wstaw, nastąpi powrót, a następnie rozpocznie się wstawiony przepływ pracy, zakończony nowym rekordem produktu dodawanym do bazy danych. Element DetailsView utrzymuje swój interfejs wstawiania, a element GridView jest automatycznie odbicia do źródła danych w celu uwzględnienia nowego produktu, jak pokazano na rysunku 18.

Produkt

Rysunek 18. Produkt "Acme Water" został dodany do bazy danych

Chociaż element GridView na rysunku 18 nie pokazuje go, pola produktu, których brakuje w interfejsie CategoryIDDetailsView , , SupplierIDQuantityPerUniti tak dalej, są przypisane NULL wartości bazy danych. Można to zobaczyć, wykonując następujące kroki:

  1. Przejdź do Eksploratora serwera w programie Visual Studio
  2. Rozszerzanie węzła NORTHWND.MDF bazy danych
  3. Kliknij prawym przyciskiem myszy Products węzeł tabeli bazy danych
  4. Wybierz pozycję Pokaż dane tabeli

Spowoduje to wyświetlenie listy wszystkich rekordów w Products tabeli. Jak pokazano na rysunku 19, wszystkie kolumny nowego produktu inne niż ProductID, ProductNamei UnitPrice mają NULL wartości.

Pola produktu, które nie zostały podane w widoku DetailsView, są przypisane wartości NULL

Rysunek 19. Pola produktu, które nie zostały podane w widoku DetailsView, są przypisane NULL wartości (kliknij, aby wyświetlić obraz pełnowymiarowy)

Możemy podać wartość domyślną inną niż NULL dla jednej lub większej liczby tych wartości kolumn, ponieważ NULL nie jest to najlepsza opcja domyślna lub dlatego, że sama kolumna bazy danych nie zezwala NULL . W tym celu możemy programowo ustawić wartości parametrów kolekcji DetailsView InputParameters . To przypisanie można wykonać w procedurze obsługi zdarzeń dla zdarzenia Elementu DetailsView ItemInserting lub zdarzenia ObjectDataSource Inserting . Ponieważ zapoznaliśmy się już z użyciem zdarzeń wstępnych i po poziomie na poziomie kontroli sieci Web danych, przyjrzyjmy się tym razem z użyciem zdarzeń ObjectDataSource.

Krok 4. Przypisywanie wartości do parametrówCategoryIDiSupplierID

W tym samouczku wyobraźmy sobie, że dla naszej aplikacji podczas dodawania nowego produktu za pomocą tego interfejsu należy przypisać CategoryID wartość i SupplierID 1. Jak wspomniano wcześniej, obiekt ObjectDataSource zawiera parę zdarzeń wstępnych i po poziomie, które są uruchamiane podczas procesu modyfikacji danych. Po wywołaniu metody Insert() obiekt ObjectDataSource najpierw zgłasza zdarzenie Inserting , a następnie wywołuje metodę, do którą została zamapowana jego Insert() metoda, a na koniec zgłasza Inserted zdarzenie. Procedura Inserting obsługi zdarzeń daje nam jedną ostatnią okazję do dostosowania parametrów wejściowych lub anulowania operacji wprost.

Uwaga

W rzeczywistej aplikacji prawdopodobnie chcesz zezwolić użytkownikowi na określenie kategorii i dostawcy lub wybranie tej wartości na podstawie niektórych kryteriów lub logiki biznesowej (zamiast ślepego wybierania identyfikatora 1). Niezależnie od tego przykład ilustruje, jak programowo ustawić wartość parametru wejściowego z zdarzenia wstępnego obiektu ObjectDataSource.

Poświęć chwilę na utworzenie procedury obsługi zdarzeń dla zdarzenia ObjectDataSource Inserting . Zwróć uwagę, że drugi parametr wejściowy programu obsługi zdarzeń jest obiektem typu ObjectDataSourceMethodEventArgs, który ma właściwość dostępu do kolekcji parametrów (InputParameters) i właściwość w celu anulowania operacji (Cancel).

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

End Sub

Na tym etapie InputParameters właściwość zawiera kolekcję ObjectDataSource InsertParameters z wartościami przypisanymi z widoku DetailsView. Aby zmienić wartość jednego z tych parametrów, po prostu użyj polecenia : e.InputParameters("paramName") = value. W związku z tym, aby ustawić CategoryID wartości i SupplierID na 1, dostosuj Inserting procedurę obsługi zdarzeń tak, aby wyglądała następująco:

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

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

Tym razem podczas dodawania nowego produktu (takiego jak Acme Soda) CategoryID kolumny i SupplierID nowego produktu są ustawione na 1 (patrz Rysunek 20).

Nowe produkty mają teraz wartości CategoryID i SupplierID ustawione na 1

Rysunek 20. Nowe produkty mają teraz wartości CategoryID i SupplierID ustawione na 1 (kliknij, aby wyświetlić obraz pełnowymiarowy)

Podsumowanie

Podczas edytowania, wstawiania i usuwania procesu zarówno kontrolka internetowa danych, jak i obiekt ObjectDataSource przechodzą przez wiele zdarzeń wstępnych i po poziomie. W tym samouczku przeanalizowaliśmy zdarzenia wstępne i zobaczyliśmy, jak używać ich do dostosowywania parametrów wejściowych lub całkowicie anulować operację modyfikacji danych zarówno z poziomu kontrolki sieci Web danych, jak i zdarzeń ObjectDataSource. W następnym samouczku przyjrzymy się tworzeniu i używaniu procedur obsługi zdarzeń dla zdarzeń po poziomie.

Szczęśliwe programowanie!

Informacje o autorze

Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została sprawdzona przez wielu pomocnych recenzentów. Recenzenci z tego samouczka byli Jackie Goor i Liz Shulok. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.