Badanie zdarzeń powiązanych ze wstawianiem, aktualizowaniem i usuwaniem (VB)
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:
- Obiekt GridView wypełnia element ObjectDataSource
UpdateParameters
unikatowymi polami identyfikacji rekordu (za pośrednictwemDataKeyNames
właściwości) wraz z wartościami wprowadzonymi przez użytkownika - Obiekt GridView wywołuje metodę ObjectDataSource
Update()
, która z kolei wywołuje odpowiednią metodę w obiekcie bazowym (ProductsDAL.UpdateProduct
w poprzednim samouczku) - 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 UpdateParameters
elementó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.
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 iUnitPrice
produktó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 QuantityPerUnit
UpdateParameters
. 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 ProductName
UnitPrice
. 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
, unitPrice
i 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 False
wartość , 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 productName
parametry , unitPrice
i 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.
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.
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.
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.
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.
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 EnableViewState
false
wartość , wystąpi ryzyko przypadkowego usunięcia lub edytowania rekordów współbieżnych użytkowników.
PoprawianieUnitPrice
formatowania
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
.
Rysunek 7. Ustaw UnitPrice
DataFormatString
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.
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
.
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.
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 UnitPrice
przez 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.
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ą NULL
UnitPrice
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.
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 UnitPrice
wartoś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 NULL
UnitPrice
s, ta konkretna strona ASP.NET nie.
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
, Updating
i 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
True
wartość , anuluje wykonywaną operację - InputParameters, czyli kolekcja
InsertParameters
,UpdateParameters
lubDeleteParameters
, w zależności od tego, czy program obsługi zdarzeń jest przeznaczony dlaInserting
zdarzenia , lubUpdating
Deleting
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ż ProductsBLL
AddProduct
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).
Rysunek 14. Ustaw listę Drop-Down tabulatora INSERT na metodę AddProduct
(kliknij, aby wyświetlić obraz pełnowymiarowy)
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.
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.
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.
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 CategoryID
DetailsView , , SupplierID
QuantityPerUnit
i tak dalej, są przypisane NULL
wartości bazy danych. Można to zobaczyć, wykonując następujące kroki:
- Przejdź do Eksploratora serwera w programie Visual Studio
- Rozszerzanie węzła
NORTHWND.MDF
bazy danych - Kliknij prawym przyciskiem myszy
Products
węzeł tabeli bazy danych - 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
, ProductName
i UnitPrice
mają NULL
wartości.
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ówCategoryID
iSupplierID
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).
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.
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla