Omówienie wstawiania, aktualizowania i usuwania danych (C#)
Autor: Scott Mitchell
W tym samouczku zobaczymy, jak mapować metody Insert(), Update() i Delete() obiektu ObjectDataSource na metody klas BLL, a także jak skonfigurować kontrolki GridView, DetailsView i FormView w celu zapewnienia możliwości modyfikacji danych.
Wprowadzenie
W ciągu ostatnich kilku samouczków omówiliśmy sposób wyświetlania danych na stronie ASP.NET przy użyciu kontrolek GridView, DetailsView i FormView. Te kontrolki po prostu współpracują z danymi dostarczonymi do nich. Często te kontrolki kontrolują dostęp do danych za pomocą kontroli źródła danych, takiej jak ObjectDataSource. Zobaczyliśmy, jak obiekt ObjectDataSource działa jako serwer proxy między stroną ASP.NET a podstawowymi danymi. Gdy obiekt GridView musi wyświetlać dane, wywołuje metodę ObjectDataSource Select()
, która z kolei wywołuje metodę z warstwy logiki biznesowej (BLL), która wywołuje metodę w tabeli TableAdapter odpowiedniej warstwy dostępu do danych (DAL), która z kolei wysyła SELECT
zapytanie do bazy danych Northwind.
Pamiętaj, że podczas tworzenia tabel TableAdapters w języku DAL w pierwszym samouczku program Visual Studio automatycznie dodał metody wstawiania, aktualizowania i usuwania danych z bazowej tabeli bazy danych. Ponadto w artykule Creating a Business Logic Layer (Tworzenie warstwy logiki biznesowej) zaprojektowaliśmy metody w usłudze BLL, które zostały wywołane do tych metod modyfikacji danych DAL.
Oprócz jej Select()
metody obiekt ObjectDataSource ma Insert()
również metody , Update()
i Delete()
. Select()
Podobnie jak metoda, te trzy metody można mapować na metody w obiekcie bazowym. Po skonfigurowaniu do wstawiania, aktualizowania lub usuwania danych kontrolki GridView, DetailsView i FormView udostępniają interfejs użytkownika do modyfikowania danych bazowych. Ten interfejs użytkownika wywołuje Insert()
metody , Update()
i Delete()
objectDataSource, które następnie wywołują skojarzone metody obiektu bazowego (zobacz Rysunek 1).
Rysunek 1. Metody , i Delete()
ObjectDataSource Insert()
Update()
służą jako serwer proxy do BLL (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
W tym samouczku zobaczymy, jak mapować metody , i Delete()
objectDataSource Insert()
Update()
na metody klas w usłudze BLL, a także jak skonfigurować kontrolki GridView, DetailsView i FormView w celu zapewnienia możliwości modyfikacji danych.
Krok 1. Tworzenie stron sieci Web wstawiania, aktualizowania i usuwania
Zanim zaczniemy badać, jak wstawiać, aktualizować i usuwać dane, najpierw zajmijmy się chwilą, aby utworzyć strony ASP.NET w naszym projekcie witryny internetowej, które będą potrzebne w tym samouczku i kilku następnych. Zacznij od dodania nowego folderu o nazwie EditInsertDelete
. Następnie dodaj następujące strony ASP.NET do tego folderu, aby skojarzyć każdą stronę ze stroną wzorcową Site.master
:
Default.aspx
Basics.aspx
DataModificationEvents.aspx
ErrorHandling.aspx
UIValidation.aspx
CustomizedUI.aspx
OptimisticConcurrency.aspx
ConfirmationOnDelete.aspx
UserLevelAccess.aspx
Rysunek 2. Dodawanie stron ASP.NET dla samouczków dotyczących modyfikacji danych
Podobnie jak w innych folderach, Default.aspx
w EditInsertDelete
folderze zostanie wyświetlona lista samouczków w jego sekcji. Pamiętaj, że kontrolka SectionLevelTutorialListing.ascx
użytkownika udostępnia tę funkcję. W związku z tym dodaj tę kontrolkę Default.aspx
użytkownika, przeciągając ją z Eksplorator rozwiązań do widoku projektu strony.
Rysunek 3. Dodawanie kontrolki SectionLevelTutorialListing.ascx
użytkownika do Default.aspx
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Na koniec dodaj strony jako wpisy do Web.sitemap
pliku. W szczególności dodaj następujący znacznik po niestandardowym formatowaniu <siteMapNode>
:
<siteMapNode title="Editing, Inserting, and Deleting"
url="~/EditInsertDelete/Default.aspx"
description="Samples of Reports that Provide Editing, Inserting,
and Deleting Capabilities">
<siteMapNode url="~/EditInsertDelete/Basics.aspx"
title="Basics"
description="Examines the basics of data modification with the
GridView, DetailsView, and FormView controls." />
<siteMapNode url="~/EditInsertDelete/DataModificationEvents.aspx"
title="Data Modification Events"
description="Explores the events raised by the ObjectDataSource
pertinent to data modification." />
<siteMapNode url="~/EditInsertDelete/ErrorHandling.aspx"
title="Error Handling"
description="Learn how to gracefully handle exceptions raised
during the data modification workflow." />
<siteMapNode url="~/EditInsertDelete/UIValidation.aspx"
title="Adding Data Entry Validation"
description="Help prevent data entry errors by providing validation." />
<siteMapNode url="~/EditInsertDelete/CustomizedUI.aspx"
title="Customize the User Interface"
description="Customize the editing and inserting user interfaces." />
<siteMapNode url="~/EditInsertDelete/OptimisticConcurrency.aspx"
title="Optimistic Concurrency"
description="Learn how to help prevent simultaneous users from
overwritting one another s changes." />
<siteMapNode url="~/EditInsertDelete/ConfirmationOnDelete.aspx"
title="Confirm On Delete"
description="Prompt a user for confirmation when deleting a record." />
<siteMapNode url="~/EditInsertDelete/UserLevelAccess.aspx"
title="Limit Capabilities Based on User"
description="Learn how to limit the data modification functionality
based on the user role or permissions." />
</siteMapNode>
Po zaktualizowaniu Web.sitemap
programu pośmiń chwilę, aby wyświetlić witrynę internetową samouczków za pośrednictwem przeglądarki. Menu po lewej stronie zawiera teraz elementy do edycji, wstawiania i usuwania samouczków.
Rysunek 4. Mapa witryny zawiera teraz wpisy do edycji, wstawiania i usuwania samouczków
Krok 2. Dodawanie i konfigurowanie kontrolki ObjectDataSource
Ponieważ kontrolki GridView, DetailsView i FormView różnią się w zależności od możliwości modyfikacji danych i układu, przyjrzyjmy się każdemu z nich indywidualnie. Zamiast mieć każdą kontrolkę przy użyciu własnego obiektu ObjectDataSource, po prostu utwórzmy pojedynczy obiekt ObjectDataSource, który może współużytkować wszystkie trzy przykłady kontrolek.
Basics.aspx
Otwórz stronę, przeciągnij element ObjectDataSource z przybornika do Projektanta, a następnie kliknij link Konfiguruj źródło danych z tagu inteligentnego. ProductsBLL
Ponieważ jest jedyną klasą BLL, która udostępnia metody edytowania, wstawiania i usuwania, skonfiguruj obiekt ObjectDataSource do używania tej klasy.
Rysunek 5. Konfigurowanie obiektu ObjectDataSource do używania ProductsBLL
klasy (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Na następnym ekranie możemy określić, jakie metody klasy są mapowane na obiekty ProductsBLL
ObjectDataSource Select()
, Insert()
, Update()
i Delete()
wybierając odpowiednią kartę i wybierając metodę z listy rozwijanej. Rysunek 6, który powinien teraz wyglądać znajomo, mapuje metodę ObjectDataSource Select()
na ProductsBLL
metodę klasy GetProducts()
. Metody Insert()
, Update()
i Delete()
można skonfigurować, wybierając odpowiednią kartę z listy u góry.
Rysunek 6. ObiektDataSource zwraca wszystkie produkty (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Na rysunkach 7, 8 i 9 są wyświetlane karty UPDATE, INSERT i DELETE obiektu ObjectDataSource. Skonfiguruj te karty, aby Insert()
metody , Update()
i Delete()
wywoływać UpdateProduct
ProductsBLL
odpowiednio metody klasy , AddProduct
i DeleteProduct
.
Rysunek 7. Mapowanie metody ObjectDataSource Update()
na ProductBLL
metodę klasy UpdateProduct
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 8. Mapowanie metody ObjectDataSource Insert()
na ProductBLL
metodę Add Product
Klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 9. Mapowanie metody ObjectDataSource Delete()
na ProductBLL
metodę klasy DeleteProduct
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Być może zauważysz, że listy rozwijane na kartach UPDATE, INSERT i DELETE zostały już wybrane. Jest to dzięki naszemu użyciu DataObjectMethodAttribute
, który dekoruje metody ProductsBLL
. Na przykład metoda DeleteProduct ma następujący podpis:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteProduct(int productID)
{
...
}
Atrybut DataObjectMethodAttribute
wskazuje przeznaczenie każdej metody, niezależnie od tego, czy jest on przeznaczony do wybierania, wstawiania, aktualizowania lub usuwania oraz czy jest to wartość domyślna. Jeśli pominięto te atrybuty podczas tworzenia klas BLL, należy ręcznie wybrać metody z kart UPDATE, INSERT i DELETE.
Po upewnieniu się, że odpowiednie ProductsBLL
metody są mapowane na metody , Update()
i Delete()
objectDataSourceInsert()
, kliknij przycisk Zakończ, aby ukończyć pracę kreatora.
Badanie znaczników objectDataSource
Po skonfigurowaniu obiektu ObjectDataSource za pomocą kreatora przejdź do widoku Źródło, aby sprawdzić wygenerowany znacznik deklaratywny. Tag <asp:ObjectDataSource>
określa obiekt bazowy i metody do wywołania. Ponadto istnieją DeleteParameters
wartości , UpdateParameters
i , które InsertParameters
są mapowane na parametry wejściowe dla ProductsBLL
klas AddProduct
, UpdateProduct
i DeleteProduct
metod:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
DeleteMethod="DeleteProduct" InsertMethod="AddProduct"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
<DeleteParameters>
<asp:Parameter Name="productID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<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" />
<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>
Obiekt ObjectDataSource zawiera parametr dla każdego z parametrów wejściowych dla skojarzonych metod, podobnie jak lista SelectParameter
s jest obecna, gdy obiekt ObjectDataSource jest skonfigurowany do wywoływania metody select, która oczekuje parametru wejściowego (na przykład GetProductsByCategoryID(categoryID)
). Jak zobaczymy wkrótce, wartości dla tych DeleteParameters
, UpdateParameters
i InsertParameters
są ustawiane automatycznie przez GridView, DetailsView i FormView przed wywołaniem metody , Update()
lub Delete()
ObjectDataSourceInsert()
. Te wartości można również ustawić programowo zgodnie z potrzebami, ponieważ omówimy je w przyszłym samouczku.
Jednym z efektów ubocznych użycia kreatora do skonfigurowania elementu ObjectDataSource jest to, że program Visual Studio ustawia właściwość OldValuesParameterFormatString na original_{0}
wartość . Ta wartość właściwości służy do uwzględnienia oryginalnych wartości edytowanych danych i jest przydatna w dwóch scenariuszach:
- Jeśli podczas edytowania rekordu użytkownicy będą mogli zmienić wartość klucza podstawowego. W takim przypadku należy podać zarówno nową wartość klucza podstawowego, jak i oryginalną wartość klucza podstawowego, aby można było znaleźć rekord z oryginalną wartością klucza podstawowego i odpowiednio zaktualizować jego wartość.
- W przypadku korzystania z optymistycznej współbieżności. Optymistyczna współbieżność to technika zapewniająca, że dwóch równoczesnych użytkowników nie zastępuje zmian nawzajem i jest tematem na potrzeby przyszłego samouczka.
Właściwość OldValuesParameterFormatString
wskazuje nazwę parametrów wejściowych w metodach aktualizacji i usuwania obiektu bazowego dla oryginalnych wartości. Omówimy tę właściwość i jej przeznaczenie bardziej szczegółowo podczas eksplorowania optymistycznej współbieżności. Wychowuję to teraz, jednak, ponieważ nasze metody BLL nie oczekują oryginalnych wartości i dlatego ważne jest, aby usunąć tę właściwość. Pozostawienie właściwości ustawionej OldValuesParameterFormatString
na wartość inną niż domyślna ({0}
) spowoduje błąd, gdy kontrolka sieci Web danych próbuje wywołać metody lub Delete()
objectDataSourceUpdate()
, ponieważ źródło ObjectDataSource spróbuje przekazać zarówno UpdateParameters
parametry wartości lubDeleteParameters
, jak i oryginalne.
Jeśli nie jest to strasznie jasne w tym momencie, nie martw się, zbadamy tę właściwość i jej narzędzie w przyszłym samouczku. Na razie wystarczy tylko usunąć tę deklarację właściwości całkowicie ze składni deklaratywnej lub ustawić wartość na wartość domyślną ({0}).
Uwaga
Jeśli po prostu wyczyścisz OldValuesParameterFormatString
wartość właściwości z okno Właściwości w widoku Projektu, właściwość nadal będzie istnieć w składni deklaratywnej, ale zostanie ustawiona na pusty ciąg. To, niestety, nadal spowoduje to ten sam problem omówiony powyżej. W związku z tym należy całkowicie usunąć właściwość ze składni deklaratywnej lub z okno Właściwości ustawić wartość domyślną {0}
na .
Krok 3. Dodawanie kontrolki sieci Web danych i konfigurowanie jej pod kątem modyfikacji danych
Po dodaniu obiektu ObjectDataSource do strony i skonfigurowaniu możemy dodać kontrolki sieci Web danych do strony, aby wyświetlić dane i udostępnić użytkownikowi końcowemu środki do ich zmodyfikowania. Przyjrzymy się oddzielnie kontrolkom GridView, DetailsView i FormView, ponieważ te kontrolki sieci Web danych różnią się w zależności od możliwości modyfikacji danych i konfiguracji.
Jak zobaczymy w pozostałej części tego artykułu, dodanie bardzo podstawowej edycji, wstawiania i usuwania obsługi za pomocą kontrolek GridView, DetailsView i FormView jest naprawdę proste, jak sprawdzanie kilku pól wyboru. Istnieje wiele subtelności i przypadków krawędzi w świecie rzeczywistym, które sprawiają, że zapewnienie takich funkcji bardziej zaangażowanych niż tylko punkt i kliknięcie. Ten samouczek koncentruje się jednak wyłącznie na udowodnieniu uproszczonych możliwości modyfikacji danych. Przyszłe samouczki przeanalizują obawy, które bez wątpienia pojawią się w rzeczywistym środowisku.
Usuwanie danych z kontrolki GridView
Zacznij od przeciągnięcia kontrolki GridView z przybornika do projektanta. Następnie powiąż obiekt ObjectDataSource z kontrolką GridView, wybierając ją z listy rozwijanej w tagu inteligentnym GridView. W tym momencie znacznik deklaratywnej kontrolki GridView będzie następujący:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False"
ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel"
HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
<asp:BoundField DataField="CategoryName"
HeaderText="CategoryName" ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="SupplierName" ReadOnly="True"
SortExpression="SupplierName" />
</Columns>
</asp:GridView>
Powiązanie kontrolki GridView z obiektem ObjectDataSource za pomocą tagu inteligentnego ma dwie korzyści:
- Pola BoundFields i CheckBoxFields są tworzone automatycznie dla każdego pola zwracanego przez obiekt ObjectDataSource. Ponadto właściwości BoundField i CheckBoxField są ustawiane na podstawie metadanych pola bazowego. Na przykład
ProductID
pola ,CategoryName
iSupplierName
są oznaczone jako tylko do odczytu wProductsDataTable
obiekcie i dlatego nie powinny być aktualizowalne podczas edytowania. Aby to uwzględnić, właściwości ReadOnly obiektów BoundFields są ustawione natrue
wartość . - Właściwość DataKeyNames jest przypisywana do pól klucza podstawowego obiektu bazowego. Jest to niezbędne w przypadku używania kontrolki GridView do edytowania lub usuwania danych, ponieważ ta właściwość wskazuje pole (lub zestaw pól), które unikatowo identyfikuje każdy rekord. Aby uzyskać więcej informacji na
DataKeyNames
temat właściwości, zapoznaj się z samouczkiem Master/Detail Using a Selectable Master GridView with a Details DetailView (Wzorzec/szczegóły przy użyciu kontrolki Selectable Master GridView ).
Element GridView może być powiązany z obiektem ObjectDataSource za pomocą okno Właściwości lub składni deklaratywnej, dlatego wymaga ręcznego dodania odpowiedniego pola BoundField i DataKeyNames
znaczników.
Kontrolka GridView zapewnia wbudowaną obsługę edytowania i usuwania na poziomie wiersza. Konfigurowanie kontrolki GridView w celu obsługi usuwania dodaje kolumnę przycisków Usuń. Gdy użytkownik końcowy kliknie przycisk Usuń dla określonego wiersza, zostanie wyświetlony komunikat zwrotny, a element GridView wykonuje następujące kroki:
- Wartości obiektu ObjectDataSource
DeleteParameters
są przypisane - Wywoływana
Delete()
jest metoda ObjectDataSource, usuwając określony rekord - Element GridView ponownie połączy się z obiektem ObjectDataSource, wywołując jego
Select()
metodę
Wartości przypisane do elementu DeleteParameters
to wartości DataKeyNames
pól dla wiersza, którego przycisk Usuń został kliknięty. Dlatego ważne jest, aby właściwość GridView była poprawnie ustawiona DataKeyNames
. Jeśli jej brakuje, DeleteParameters
zostanie przypisana null
wartość w kroku 1, co z kolei nie spowoduje usunięcia rekordów w kroku 2.
Uwaga
Kolekcja DataKeys
jest przechowywana w stanie sterowania kontrolki GridView, co oznacza, że DataKeys
wartości będą zapamiętowywane po wyświetleniu, nawet jeśli stan widoku kontrolki GridView został wyłączony. Jednak bardzo ważne jest, aby stan widoku pozostał włączony dla obiektów GridView obsługujących edytowanie lub usuwanie (zachowanie domyślne). Jeśli ustawisz właściwość GridView na false
, zachowanie edytowania EnableViewState
i usuwania będzie działać prawidłowo dla pojedynczego użytkownika, ale jeśli istnieją współbieżni użytkownicy usuwający dane, istnieje możliwość przypadkowego usunięcia lub edytowania rekordów, których nie zamierzali.
To samo ostrzeżenie dotyczy również elementów DetailsView i FormView.
Aby dodać możliwości usuwania do kontrolki GridView, po prostu przejdź do tagu inteligentnego i zaznacz pole wyboru Włącz usuwanie.
Rysunek 10. Zaznacz pole wyboru Włącz usuwanie
Zaznacz pole wyboru Włącz usuwanie z tagu inteligentnego dodaje pole CommandField do kontrolki GridView. Pole CommandField renderuje kolumnę w elementy GridView z przyciskami służącymi do wykonywania co najmniej jednego z następujących zadań: wybierania rekordu, edytowania rekordu i usuwania rekordu. Wcześniej widzieliśmy pole commandField w akcji z wybieraniem rekordów w master/detail using a Selectable Master GridView with a Details DetailView tutorial (Wybieranie elementu Master GridView z elementem DetailsView ).
Pole CommandField zawiera wiele ShowXButton
właściwości, które wskazują serię przycisków wyświetlanych w pole polecenia. Zaznaczając pole wyboru Włącz usuwanie pole polecenia, którego ShowDeleteButton
właściwość została true
dodana do kolekcji Kolumny kontrolki GridView.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
... BoundFields removed for brevity ...
</Columns>
</asp:GridView>
W tym momencie wierzymy w to, czy nie, możemy dodać obsługę usuwania do kontrolki GridView! Jak pokazano na rysunku 11, podczas odwiedzania tej strony za pośrednictwem przeglądarki jest wyświetlana kolumna przycisków Usuń.
Rysunek 11. Pole polecenia dodaje kolumnę przycisków usuwania (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Jeśli tworzysz ten samouczek od podstaw samodzielnie, podczas testowania tej strony kliknięcie przycisku Usuń spowoduje wystąpienie wyjątku. Kontynuuj czytanie, aby dowiedzieć się, dlaczego te wyjątki zostały zgłoszone i jak je naprawić.
Uwaga
Jeśli korzystasz z pobierania towarzyszącego temu samouczkowi, te problemy zostały już uwzględnione. Zachęcam jednak do zapoznania się ze szczegółowymi informacjami wymienionymi poniżej, aby pomóc zidentyfikować problemy, które mogą wystąpić i odpowiednie obejścia.
Jeśli podczas próby usunięcia produktu otrzymasz wyjątek podobny do komunikatu "ObjectDataSource 'ObjectDataSource1' nie można odnaleźć metody innej niż ogólna "DeleteProduct", która ma parametry: productID, original_ProductID", prawdopodobnie nie pamiętasz usunięcia OldValuesParameterFormatString
właściwości z obiektu ObjectDataSource. Po określeniu OldValuesParameterFormatString
właściwości obiekt ObjectDataSource próbuje przekazać zarówno parametry wejściowe, jak productID
i original_ProductID
do DeleteProduct
metody . DeleteProduct
jednak akceptuje tylko jeden parametr wejściowy, dlatego wyjątek. OldValuesParameterFormatString
Usunięcie właściwości (lub ustawienie jej na {0}
wartość ) powoduje, że właściwość ObjectDataSource nie próbuje przekazać oryginalnego parametru wejściowego.
Rysunek 12. Upewnij się, że OldValuesParameterFormatString
właściwość została wyczyszczone (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Nawet jeśli właściwość została usunięta OldValuesParameterFormatString
, nadal otrzymasz wyjątek podczas próby usunięcia produktu z komunikatem: "Instrukcja DELETE powoduje konflikt z ograniczeniem REFERENCE "FK_Order_Details_Products". Baza danych Northwind zawiera ograniczenie klucza obcego między Order Details
tabelą i Products
, co oznacza, że nie można usunąć produktu z systemu, jeśli w Order Details
tabeli znajduje się co najmniej jeden rekord. Ponieważ każdy produkt w bazie danych Northwind ma co najmniej jeden rekord w Order Details
systemie , nie możemy usunąć żadnych produktów, dopóki nie usuniemy rekordów szczegółów zamówienia skojarzonego z produktem.
Rysunek 13. Ograniczenie klucza obcego uniemożliwia usunięcie produktów (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
W naszym samouczku po prostu usuńmy wszystkie rekordy z Order Details
tabeli. W rzeczywistej aplikacji musimy wykonać jedną z następujących czynności:
- Inny ekran umożliwiający zarządzanie informacjami o szczegółach zamówienia
- Rozszerzanie
DeleteProduct
metody w celu uwzględnienia logiki w celu usunięcia szczegółów zamówienia określonego produktu - Modyfikowanie zapytania SQL używanego przez narzędzie TableAdapter w celu uwzględnienia usunięcia szczegółów zamówienia określonego produktu
Po prostu usuńmy wszystkie rekordy z tabeli, Order Details
aby obejść ograniczenie klucza obcego. Przejdź do Eksploratora serwera w programie Visual Studio, kliknij prawym przyciskiem myszy NORTHWND.MDF
węzeł i wybierz pozycję Nowe zapytanie. Następnie w oknie zapytania uruchom następującą instrukcję SQL: DELETE FROM [Order Details]
Rysunek 14. Usuwanie wszystkich rekordów z Order Details
tabeli (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po wyczyszczeniu Order Details
tabeli kliknięcie przycisku Usuń spowoduje usunięcie produktu bez błędu. Jeśli kliknięcie przycisku Usuń nie spowoduje usunięcia produktu, sprawdź, czy właściwość GridView DataKeyNames
jest ustawiona na pole klucza podstawowego (ProductID
).
Uwaga
Po kliknięciu przycisku Usuń następuje wycofanie i usunięcie rekordu. Może to być niebezpieczne, ponieważ można łatwo przypadkowo kliknąć przycisk Usuń niewłaściwego wiersza. W przyszłym samouczku zobaczymy, jak dodać potwierdzenie po stronie klienta podczas usuwania rekordu.
Edytowanie danych za pomocą kontrolki GridView
Oprócz usuwania kontrolka GridView zapewnia również wbudowaną obsługę edycji na poziomie wiersza. Konfigurowanie kontrolki GridView w celu obsługi edycji powoduje dodanie kolumny przycisków Edytuj. Z perspektywy użytkownika końcowego kliknięcie przycisku Edytuj wiersza powoduje, że wiersz staje się edytowalny, zamieniając komórki w pola tekstowe zawierające istniejące wartości i zastępując przycisk Edytuj przyciskami Aktualizuj i Anuluj. Po wprowadzeniu żądanych zmian użytkownik końcowy może kliknąć przycisk Aktualizuj, aby zatwierdzić zmiany lub przycisk Anuluj, aby je odrzucić. W obu przypadkach po kliknięciu przycisku Aktualizuj lub Anuluj widok GridView powróci do stanu wstępnego edytowania.
Z naszej perspektywy jako deweloper strony, gdy użytkownik końcowy kliknie przycisk Edytuj dla określonego wiersza, zostanie wyświetlony komunikat zwrotny, a element GridView wykonuje następujące kroki:
- Właściwość GridView jest przypisywana
EditItemIndex
do indeksu wiersza, którego przycisk Edytuj został kliknięty - Element GridView ponownie połączy się z obiektem ObjectDataSource, wywołując jego
Select()
metodę - Indeks wierszy zgodny z elementem
EditItemIndex
jest renderowany w trybie edycji. W tym trybie przycisk Edytuj jest zastępowany przez przyciski Aktualizuj i Anuluj i BoundFields, którychReadOnly
właściwości to False (wartość domyślna) są renderowane jako kontrolki sieci Web TextBox, którychText
właściwości są przypisane do wartości pól danych.
Na tym etapie znaczniki są zwracane do przeglądarki, co umożliwia użytkownikowi końcowemu wprowadzanie jakichkolwiek zmian w danych wiersza. Gdy użytkownik kliknie przycisk Aktualizuj, nastąpi wycofanie, a element GridView wykonuje następujące kroki:
- Wartości obiektu ObjectDataSource
UpdateParameters
są przypisywane wartości wprowadzone przez użytkownika końcowego do interfejsu edycji obiektu GridView - Wywoływana
Update()
jest metoda ObjectDataSource, aktualizując określony rekord - Element GridView ponownie połączy się z obiektem ObjectDataSource, wywołując jego
Select()
metodę
Wartości klucza podstawowego UpdateParameters
przypisane do tabeli w kroku 1 pochodzą z wartości określonych we DataKeyNames
właściwości, natomiast wartości klucza innego niż podstawowy pochodzą z tekstu w kontrolkach sieci Web TextBox dla edytowanego wiersza. Podobnie jak w przypadku usuwania, ważne jest, aby właściwość GridView była poprawnie ustawiona DataKeyNames
. Jeśli jej brakuje, UpdateParameters
wartość klucza podstawowego null
zostanie przypisana w kroku 1, co z kolei nie spowoduje żadnych zaktualizowanych rekordów w kroku 2.
Funkcję edycji można aktywować, zaznaczając pole wyboru Włącz edytowanie w tagu inteligentnym GridView.
Rysunek 15. Zaznacz pole wyboru Włącz edytowanie
Zaznaczenie pola wyboru Włącz edycję spowoduje dodanie pola CommandField (w razie potrzeby) i ustawienie jej ShowEditButton
właściwości na true
. Jak pokazano wcześniej, pole CommandField zawiera wiele ShowXButton
właściwości, które wskazują serię przycisków wyświetlanych w pole polecenia. Zaznaczenie pola wyboru Włącz edycję ShowEditButton
powoduje dodanie właściwości do istniejącego pola polecenia:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True" />
... BoundFields removed for brevity ...
</Columns>
</asp:GridView>
To wszystko, co jest do dodawania podstawowego wsparcia do edycji. Jak pokazano na rysunku16, interfejs edycji jest raczej surowy dla każdego obiektu BoundField, którego ReadOnly
właściwość jest ustawiona na false
(wartość domyślna) jest renderowana jako pole tekstowe. Obejmuje to pola takie jak CategoryID
i SupplierID
, które są kluczami do innych tabel.
Rysunek 16. Kliknięcie przycisku Edytuj Chai powoduje wyświetlenie wiersza w trybie edycji (kliknij, aby wyświetlić obraz pełnowymiarowy)
Oprócz bezpośredniego edytowania wartości klucza obcego przez użytkowników interfejs edycji nie jest zgodny z następującymi sposobami:
- Jeśli użytkownik wprowadzi element
CategoryID
lubSupplierID
, który nie istnieje w bazie danych,UPDATE
będzie naruszać ograniczenie klucza obcego, co powoduje zgłaszanie wyjątku. - Interfejs edycji nie zawiera żadnej weryfikacji. Jeśli nie podasz wymaganej wartości (takiej jak
ProductName
), lub wprowadź wartość ciągu, w której oczekiwana jest wartość liczbowa (na przykład wprowadzenie wartości "Zbyt wiele!" wUnitPrice
polu tekstowym), zostanie zgłoszony wyjątek. W przyszłym samouczku dowiesz się, jak dodać kontrolki walidacji do interfejsu użytkownika edycji. - Obecnie wszystkie pola produktów, które nie są tylko do odczytu, muszą być uwzględnione w elementy GridView. Gdybyśmy usunęli pole z kontrolki GridView, powiedzmy
UnitPrice
, podczas aktualizowania danych kontrolka GridView nie ustawiłabyUnitPrice
UpdateParameters
wartości, co spowoduje zmianęNULL
wartości rekorduUnitPrice
bazy danych na wartość. Podobnie, jeśli wymagane pole, takie jakProductName
, zostanie usunięte z kontrolki GridView, aktualizacja zakończy się niepowodzeniem z tym samym wyjątkiem "ProductName" kolumny "ProductName" nie zezwala na wyjątki null wymienione powyżej. - Formatowanie interfejsu edycji pozostawia wiele do życzenia. Element
UnitPrice
jest wyświetlany z czterema punktami dziesiętnymi. Najlepiej, aby wartościCategoryID
iSupplierID
zawierały listy DropDownLists, które zawierają kategorie i dostawców w systemie.
Są to wszystkie braki, z którymi będziemy musieli żyć na razie, ale zostaną one rozwiązane w przyszłych samouczkach.
Wstawianie, edytowanie i usuwanie danych za pomocą kontrolki DetailsView
Jak pokazano we wcześniejszych samouczkach, kontrolka DetailsView wyświetla jeden rekord naraz i, podobnie jak GridView, umożliwia edytowanie i usuwanie aktualnie wyświetlanego rekordu. Zarówno środowisko użytkownika końcowego podczas edytowania i usuwania elementów z widoku DetailsView, jak i przepływu pracy po stronie ASP.NET jest identyczne z elementem GridView. Element DetailsView różni się od kontrolki GridView, ponieważ zapewnia również wbudowaną obsługę wstawiania.
Aby zademonstrować możliwości modyfikacji danych elementu GridView, zacznij od dodania kontrolki DetailsView do Basics.aspx
strony powyżej istniejącej kontrolki GridView i powiązania jej z istniejącym obiektem ObjectDataSource za pomocą tagu inteligentnego Kontrolka DetailsView. Następnie wyczyść właściwości kontrolki DetailsView Height
i Width
zaznacz opcję Włącz stronicowanie z tagu inteligentnego. Aby włączyć edytowanie, wstawianie i usuwanie obsługi, po prostu zaznacz pola wyboru Włącz edytowanie, Włącz wstawianie i Włącz usuwanie w tagu inteligentnym.
Rysunek 17. Konfigurowanie kontrolki DetailsView w celu obsługi edycji, wstawiania i usuwania
Podobnie jak w przypadku kontrolki GridView, dodawanie edycji, wstawiania lub usuwania obsługi powoduje dodanie pola commandfield do kontrolki DetailsView, jak pokazuje następująca składnia deklaratywna:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True">
<Fields>
<asp:BoundField DataField="ProductID"
HeaderText="ProductID" InsertVisible="False"
ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice"
HeaderText="UnitPrice" SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel"
HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
<asp:BoundField DataField="CategoryName"
HeaderText="CategoryName" ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="SupplierName" ReadOnly="True"
SortExpression="SupplierName" />
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
Pamiętaj, że dla kontrolki DetailsView pole polecenia jest domyślnie wyświetlane na końcu kolekcji Columns. Ponieważ pola kontrolki DetailsView są renderowane jako wiersze, pole polecenia jest wyświetlane jako wiersz z przyciskami Wstaw, Edytuj i Usuń w dolnej części widoku Szczegółów.
Rysunek 18. Konfigurowanie kontrolki DetailsView do obsługi edycji, wstawiania i usuwania (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Kliknięcie przycisku Usuń powoduje uruchomienie tej samej sekwencji zdarzeń, co w przypadku elementu GridView: postback; następnie element DetailsView wypełnia jego obiekt ObjectDataSource na DataKeyNames
podstawie wartości i zakończył wywołanie metody ObjectDataSource DeleteParameters
Delete()
, która rzeczywiście usuwa produkt z bazy danych. Edytowanie w widoku DetailsView działa również w sposób identyczny z funkcją GridView.
W przypadku wstawiania użytkownik końcowy jest wyświetlany z przyciskiem Nowy, który po kliknięciu renderuje element DetailsView w trybie wstawiania. W przypadku opcji "tryb wstawiania" przycisk Nowy jest zastępowany przyciskami Wstaw i Anuluj, a wyświetlane są tylko pola powiązane, których InsertVisible
właściwość jest ustawiona na true
(wartość domyślna). Te pola danych zidentyfikowane jako pola automatycznego zwiększania, takie jak ProductID
, mają ustawioną właściwość InsertVisible na false
wartość podczas powiązania kontrolki DetailsView ze źródłem danych za pomocą tagu inteligentnego.
Po powiązaniu źródła danych z kontrolką DetailsView za pomocą tagu inteligentnego program Visual Studio ustawia InsertVisible
właściwość na false
wartość tylko dla pól automatycznego zwiększania. Pola tylko do odczytu, takie jak CategoryName
i SupplierName
, będą wyświetlane w interfejsie użytkownika "tryb wstawiania", chyba że ich InsertVisible
właściwość jest jawnie ustawiona na false
. Pośmiń chwilę, aby ustawić właściwości tych dwóch pól InsertVisible
na false
wartość , za pomocą składni deklaratywnej kontrolki DetailsView lub linku Edytuj pola w tagu inteligentnym. Rysunek 19 przedstawia ustawienie InsertVisible
właściwości false
, klikając link Edytuj pola.
Rysunek 19. Firma Northwind Traders oferuje teraz herbatę Acme (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ustawieniu InsertVisible
właściwości wyświetl Basics.aspx
stronę w przeglądarce i kliknij przycisk Nowy. Rysunek 20 przedstawia element DetailsView podczas dodawania nowego napoju Acme Tea do naszej linii produktu.
Rysunek 20. Firma Northwind Traders oferuje teraz herbatę Acme (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po wprowadzeniu szczegółów aplikacji Acme Tea i kliknięciu przycisku Wstaw następuje powrót i dodanie nowego rekordu Products
do tabeli bazy danych. Ponieważ ten element DetailsView wyświetla listę produktów w kolejności, w której istnieją w tabeli bazy danych, musimy stronicować ostatni produkt, aby zobaczyć nowy produkt.
Rysunek 21. Szczegóły herbaty Acme (kliknij, aby wyświetlić obraz pełnowymiarowy)
Uwaga
Właściwość CurrentMode elementu DetailsView wskazuje wyświetlany interfejs i może być jedną z następujących wartości: Edit
, lub Insert
ReadOnly
. Właściwość DefaultMode wskazuje tryb, do którego funkcja DetailsView powraca po zakończeniu edycji lub wstawiania i jest przydatna do wyświetlania elementu DetailsView, który jest trwale w trybie edycji lub wstawiania.
Punkt i kliknięcie przycisku wstawiania i edytowania możliwości kontrolki DetailsView nie ma takich samych ograniczeń jak kontrolka GridView: użytkownik musi wprowadzić istniejące CategoryID
wartości i SupplierID
za pośrednictwem pola tekstowego; interfejs nie ma żadnej logiki walidacji; wszystkie pola produktu, które nie zezwalają na NULL
wartości lub nie mają wartości domyślnej określonej na poziomie bazy danych, muszą zostać uwzględnione w interfejsie wstawiania, i tak dalej.
Techniki, które przeanalizujemy pod kątem rozszerzania i ulepszania interfejsu edytowania kontrolki GridView w przyszłych artykułach, można również zastosować do edycji i wstawiania interfejsów kontrolki DetailsView.
Używanie widoku FormView do bardziej elastycznego interfejsu użytkownika modyfikacji danych
Obiekt FormView oferuje wbudowaną obsługę wstawiania, edytowania i usuwania danych, ale ponieważ używa szablonów zamiast pól, nie ma miejsca do dodawania pól BoundFields ani CommandField używanych przez kontrolki GridView i DetailsView w celu udostępnienia interfejsu modyfikacji danych. Zamiast tego ten interfejs umożliwia kontrolkom sieci Web zbieranie danych wejściowych użytkownika podczas dodawania nowego elementu lub edytowania istniejącego elementu wraz z przyciskami Nowy, Edytuj, Usuń, Wstaw, Aktualizuj i Anuluj należy dodać ręcznie do odpowiednich szablonów. Na szczęście program Visual Studio automatycznie utworzy wymagany interfejs podczas wiązania widoku FormView ze źródłem danych za pomocą listy rozwijanej w tagu inteligentnym.
Aby zilustrować te techniki, zacznij od dodania widoku FormView do Basics.aspx
strony i z tagu inteligentnego kontrolki FormView powiąż ją z już utworzonym obiektem ObjectDataSource. Spowoduje to wygenerowanie kontrolek , InsertItemTemplate
i ItemTemplate
dla kontrolki EditItemTemplate
FormView z kontrolkami sieci Web TextBox w celu zbierania kontrolek wejściowych i kontrolek sieci Web przycisku użytkownika dla przycisków Nowy, Edytuj, Usuń, Wstaw, Aktualizuj i Anuluj. Ponadto właściwość FormView DataKeyNames
jest ustawiona na pole klucza podstawowego (ProductID
) obiektu zwróconego przez obiekt ObjectDataSource. Na koniec zaznacz opcję Włącz stronicowanie w tagu inteligentnym kontrolki FormView.
Poniżej przedstawiono znaczniki deklaratywne dla elementu FormView po powiązaniu elementu FormView ItemTemplate
z obiektem ObjectDataSource. Domyślnie każde pole produktu innej niż wartość logiczna jest powiązane z właściwością kontrolki Sieci Web Etykieta, podczas gdy każde pole wartości logicznej (Discontinued
) jest powiązane Text
z Checked
właściwością wyłączonej kontrolki checkbox sieci Web. Aby przyciski Nowy, Edytuj i Usuń wyzwalały pewne zachowanie kontrolki FormView po kliknięciu, konieczne jest ustawienie ich CommandName
wartości odpowiednio na New
, Edit
i Delete
.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
...
</EditItemTemplate>
<InsertItemTemplate>
...
</InsertItemTemplate>
<ItemTemplate>
ProductID:
<asp:Label ID="ProductIDLabel" runat="server"
Text='<%# Eval("ProductID") %>'></asp:Label><br />
ProductName:
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Bind("ProductName") %>'>
</asp:Label><br />
SupplierID:
<asp:Label ID="SupplierIDLabel" runat="server"
Text='<%# Bind("SupplierID") %>'>
</asp:Label><br />
CategoryID:
<asp:Label ID="CategoryIDLabel" runat="server"
Text='<%# Bind("CategoryID") %>'>
</asp:Label><br />
QuantityPerUnit:
<asp:Label ID="QuantityPerUnitLabel" runat="server"
Text='<%# Bind("QuantityPerUnit") %>'>
</asp:Label><br />
UnitPrice:
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# Bind("UnitPrice") %>'></asp:Label><br />
UnitsInStock:
<asp:Label ID="UnitsInStockLabel" runat="server"
Text='<%# Bind("UnitsInStock") %>'>
</asp:Label><br />
UnitsOnOrder:
<asp:Label ID="UnitsOnOrderLabel" runat="server"
Text='<%# Bind("UnitsOnOrder") %>'>
</asp:Label><br />
ReorderLevel:
<asp:Label ID="ReorderLevelLabel" runat="server"
Text='<%# Bind("ReorderLevel") %>'>
</asp:Label><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked='<%# Bind("Discontinued") %>'
Enabled="false" /><br />
CategoryName:
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Bind("CategoryName") %>'>
</asp:Label><br />
SupplierName:
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Bind("SupplierName") %>'>
</asp:Label><br />
<asp:LinkButton ID="EditButton" runat="server"
CausesValidation="False" CommandName="Edit"
Text="Edit">
</asp:LinkButton>
<asp:LinkButton ID="DeleteButton" runat="server"
CausesValidation="False" CommandName="Delete"
Text="Delete">
</asp:LinkButton>
<asp:LinkButton ID="NewButton" runat="server"
CausesValidation="False" CommandName="New"
Text="New">
</asp:LinkButton>
</ItemTemplate>
</asp:FormView>
Rysunek 22 przedstawia widok FormView ItemTemplate
podczas przeglądania za pośrednictwem przeglądarki. Każde pole produktu znajduje się na liście z przyciskami Nowy, Edytuj i Usuń u dołu.
Rysunek 22. Kontrolka Defaut FormView ItemTemplate
wyświetla listę każdego pola produktu wraz z przyciskami Nowy, Edytuj i Usuń (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Podobnie jak w przypadku kontrolki GridView i DetailsView, kliknięcie przycisku Usuń lub dowolnego przycisku, elementu LinkButton lub elementu ImageButton, którego CommandName
właściwość jest ustawiona na wartość Delete powoduje, że element ObjectDataSource jest wypełniany na podstawie wartości kontrolki FormView DataKeyNames
i wywołuje metodę ObjectDataSource DeleteParameters
Delete()
.
Po kliknięciu przycisku Edytuj zostanie wyświetlony komunikat zwrotny, a dane są odtwarzane do EditItemTemplate
elementu , który jest odpowiedzialny za renderowanie interfejsu edycji. Ten interfejs zawiera kontrolki sieci Web do edytowania danych wraz z przyciskami Aktualizuj i Anuluj. Wartość domyślna EditItemTemplate
wygenerowana przez program Visual Studio zawiera etykietę dla wszystkich pól automatycznego przyrostu (ProductID
), pole TextBox dla każdego pola wartości innej niż wartość logiczna i pole CheckBox dla każdego pola wartości logicznej. To zachowanie jest bardzo podobne do automatycznie generowanych pól BoundFields w kontrolkach GridView i DetailsView.
Uwaga
Jednym z małych problemów z automatycznym generowaniem kontrolki EditItemTemplate
FormView jest to, że renderuje kontrolki Web TextBox dla tych pól, które są tylko do odczytu, takich jak CategoryName
i SupplierName
. Wkrótce zobaczymy, jak to uwzględnić.
Kontrolki TextBox w obiekcie EditItemTemplate
mają właściwość Text
powiązaną z wartością odpowiedniego pola danych przy użyciu dwukierunkowego powiązania danych. Dwukierunkowe powiązanie danych, oznaczone przez <%# Bind("dataField") %>
element , wykonuje powiązanie danych zarówno podczas wiązania danych z szablonem, jak i podczas wypełniania parametrów objectDataSource do wstawiania lub edytowania rekordów. Oznacza to, że gdy użytkownik kliknie przycisk Edytuj z ItemTemplate
metody , Bind()
metoda zwraca określoną wartość pola danych. Po wprowadzeniu zmian przez użytkownika i kliknięciu przycisku Aktualizuj wartości opublikowane z powrotem odpowiadające polam danych określonym przy użyciu Bind()
są stosowane do obiektu ObjectDataSource UpdateParameters
. Alternatywnie jednokierunkowe powiązanie danych, oznaczone przez <%# Eval("dataField") %>
element , pobiera tylko wartości pól danych podczas wiązania danych z szablonem i nie zwraca wartości wprowadzonych przez użytkownika do parametrów źródła danych podczas ogłaszania zwrotnego.
Poniższy znacznik deklaratywny pokazuje element FormView .EditItemTemplate
Należy pamiętać, że Bind()
metoda jest używana w składni powiązania danych w tym miejscu i że kontrolki Sieci Web aktualizuj i anuluj przycisk mają odpowiednio ustawione właściwości CommandName
.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
ProductID:
<asp:Label ID="ProductIDLabel1" runat="server"
Text="<%# Eval("ProductID") %>"></asp:Label><br />
ProductName:
<asp:TextBox ID="ProductNameTextBox" runat="server"
Text="<%# Bind("ProductName") %>">
</asp:TextBox><br />
SupplierID:
<asp:TextBox ID="SupplierIDTextBox" runat="server"
Text="<%# Bind("SupplierID") %>">
</asp:TextBox><br />
CategoryID:
<asp:TextBox ID="CategoryIDTextBox" runat="server"
Text="<%# Bind("CategoryID") %>">
</asp:TextBox><br />
QuantityPerUnit:
<asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
Text="<%# Bind("QuantityPerUnit") %>">
</asp:TextBox><br />
UnitPrice:
<asp:TextBox ID="UnitPriceTextBox" runat="server"
Text="<%# Bind("UnitPrice") %>">
</asp:TextBox><br />
UnitsInStock:
<asp:TextBox ID="UnitsInStockTextBox" runat="server"
Text="<%# Bind("UnitsInStock") %>">
</asp:TextBox><br />
UnitsOnOrder:
<asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
Text="<%# Bind("UnitsOnOrder") %>">
</asp:TextBox><br />
ReorderLevel:
<asp:TextBox ID="ReorderLevelTextBox" runat="server"
Text="<%# Bind("ReorderLevel") %>">
</asp:TextBox><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked="<%# Bind("Discontinued") %>" /><br />
CategoryName:
<asp:TextBox ID="CategoryNameTextBox" runat="server"
Text="<%# Bind("CategoryName") %>">
</asp:TextBox><br />
SupplierName:
<asp:TextBox ID="SupplierNameTextBox" runat="server"
Text="<%# Bind("SupplierName") %>">
</asp:TextBox><br />
<asp:LinkButton ID="UpdateButton" runat="server"
CausesValidation="True" CommandName="Update"
Text="Update">
</asp:LinkButton>
<asp:LinkButton ID="UpdateCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</EditItemTemplate>
<InsertItemTemplate>
...
</InsertItemTemplate>
<ItemTemplate>
...
</ItemTemplate>
</asp:FormView>
Nasz EditItemTemplate
element , w tym momencie spowoduje zgłoszenie wyjątku, jeśli spróbujemy go użyć. Problem polega na tym, że CategoryName
pola i SupplierName
są renderowane jako kontrolki sieci Web TextBox w elem.EditItemTemplate
Musimy zmienić te pola tekstowe na Etykiety lub całkowicie je usunąć. Po prostu usuńmy je całkowicie z obiektu EditItemTemplate
.
Rysunek 23 przedstawia widok FormView w przeglądarce po kliknięciu przycisku Edytuj dla pozycji Chai. Zwróć uwagę, że SupplierName
pola i CategoryName
wyświetlane w obiekcie ItemTemplate
nie są już obecne, ponieważ po prostu usunęliśmy je z obiektu EditItemTemplate
. Po kliknięciu przycisku Aktualizuj widok FormView przechodzi przez tę samą sekwencję kroków co kontrolki GridView i DetailsView.
Rysunek 23. Domyślnie pole EditItemTemplate
Pokaż każde edytowalne pole produktu jako pole tekstowe lub pole wyboru (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po kliknięciu przycisku Wstaw element FormView ItemTemplate
zostanie wyświetlony komunikat zwrotny. Jednak żadne dane nie są powiązane z elementem FormView, ponieważ jest dodawany nowy rekord. Interfejs InsertItemTemplate
zawiera kontrolki sieci Web służące do dodawania nowego rekordu wraz z przyciskami Wstaw i Anuluj. Wartość domyślna InsertItemTemplate
wygenerowana przez program Visual Studio zawiera pole TextBox dla każdego pola wartości innej niż wartość logiczna i pole wyboru dla każdego pola wartości logicznej, podobnie jak w przypadku interfejsu wygenerowanego EditItemTemplate
automatycznie. Kontrolki TextBox mają swoją Text
właściwość powiązaną z wartością odpowiedniego pola danych przy użyciu dwukierunkowego powiązania danych.
Poniższy znacznik deklaratywny pokazuje element FormView .InsertItemTemplate
Należy pamiętać, że Bind()
metoda jest używana w składni powiązania danych w tym miejscu i że kontrolki Wstaw i Anuluj przycisk w sieci Web mają odpowiednio ustawione właściwości CommandName
.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
...
</EditItemTemplate>
<InsertItemTemplate>
ProductName:
<asp:TextBox ID="ProductNameTextBox" runat="server"
Text="<%# Bind("ProductName") %>">
</asp:TextBox><br />
SupplierID:
<asp:TextBox ID="SupplierIDTextBox" runat="server"
Text="<%# Bind("SupplierID") %>">
</asp:TextBox><br />
CategoryID:
<asp:TextBox ID="CategoryIDTextBox" runat="server"
Text="<%# Bind("CategoryID") %>">
</asp:TextBox><br />
QuantityPerUnit:
<asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
Text="<%# Bind("QuantityPerUnit") %>">
</asp:TextBox><br />
UnitPrice:
<asp:TextBox ID="UnitPriceTextBox" runat="server"
Text="<%# Bind("UnitPrice") %>">
</asp:TextBox><br />
UnitsInStock:
<asp:TextBox ID="UnitsInStockTextBox" runat="server"
Text="<%# Bind("UnitsInStock") %>">
</asp:TextBox><br />
UnitsOnOrder:
<asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
Text="<%# Bind("UnitsOnOrder") %>">
</asp:TextBox><br />
ReorderLevel:
<asp:TextBox ID="ReorderLevelTextBox" runat="server"
Text="<%# Bind("ReorderLevel") %>">
</asp:TextBox><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked="<%# Bind("Discontinued") %>" /><br />
CategoryName:
<asp:TextBox ID="CategoryNameTextBox" runat="server"
Text="<%# Bind("CategoryName") %>">
</asp:TextBox><br />
SupplierName:
<asp:TextBox ID="SupplierNameTextBox" runat="server"
Text="<%# Bind("SupplierName") %>">
</asp:TextBox><br />
<asp:LinkButton ID="InsertButton" runat="server"
CausesValidation="True" CommandName="Insert"
Text="Insert">
</asp:LinkButton>
<asp:LinkButton ID="InsertCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</InsertItemTemplate>
<ItemTemplate>
...
</ItemTemplate>
</asp:FormView>
Istnieje subtelność funkcji automatycznego generowania elementu FormView dla elementu InsertItemTemplate
. W szczególności kontrolki sieci Web TextBox są tworzone nawet dla tych pól, które są tylko do odczytu, takie jak CategoryName
i SupplierName
. Podobnie jak w przypadku elementu EditItemTemplate
, musimy usunąć te pola TextBoxes z elementu InsertItemTemplate
.
Rysunek 24 przedstawia element FormView w przeglądarce podczas dodawania nowego produktu Acme Coffee. Zwróć uwagę, że SupplierName
pola i CategoryName
wyświetlane w elemecie ItemTemplate
nie są już obecne, ponieważ zostały usunięte. Po kliknięciu przycisku Wstaw widok FormView przechodzi przez tę samą sekwencję kroków co kontrolka DetailsView, dodając nowy rekord do Products
tabeli. Rysunek 25 przedstawia szczegóły produktu Acme Coffee w widoku FormView po jego wstawieniu.
Rysunek 24. InsertItemTemplate
Dyktowanie interfejsu wstawiania kontrolki FormView (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 25. Szczegóły nowego produktu, Acme Coffee są wyświetlane w widoku FormView (kliknij, aby wyświetlić obraz pełnowymiarowy)
Oddzielając interfejsy tylko do odczytu, edycji i wstawiania do trzech oddzielnych szablonów, kontrolka FormView umożliwia dokładniejszy stopień kontroli nad tymi interfejsami niż Kontrolka DetailsView i GridView.
Uwaga
Podobnie jak w przypadku kontrolki DetailsView, właściwość Kontrolka CurrentMode
FormView wskazuje wyświetlany interfejs, a jego DefaultMode
właściwość wskazuje tryb, do których widok FormView powraca po zakończeniu edycji lub wstawiania.
Podsumowanie
W tym samouczku omówiliśmy podstawy wstawiania, edytowania i usuwania danych przy użyciu kontrolki GridView, DetailsView i FormView. Wszystkie trzy z tych kontrolek zapewniają pewien poziom wbudowanych możliwości modyfikacji danych, które można wykorzystać bez konieczności pisania pojedynczego wiersza kodu na stronie ASP.NET dzięki kontrolkom sieci Web danych i obiektowi ObjectDataSource. Jednak proste techniki punktów i kliknięć sprawiają, że interfejs użytkownika modyfikacji danych jest dość słaby i naiwny. Aby zapewnić walidację, wstrzyknąć wartości programowe, bezpiecznie obsługiwać wyjątki, dostosowywać interfejs użytkownika itd., musimy polegać na bevy technik, które zostaną omówione w kolejnych kilku samouczkach.
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 24 godzinach. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com. lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.