Dostosowywanie interfejsu modyfikacji danych (VB)
Autor: Scott Mitchell
W tym samouczku przyjrzymy się, jak dostosować interfejs edytowalnego obiektu GridView, zastępując standardowe kontrolki TextBox i CheckBox alternatywnymi kontrolkami wejściowymi sieci Web.
Wprowadzenie
Kontrolki BoundFields i CheckBoxFields używane przez kontrolki GridView i DetailsView upraszczają proces modyfikowania danych ze względu na możliwość renderowania interfejsów tylko do odczytu, edytowalnych i wstawiania. Te interfejsy można renderować bez konieczności dodawania dodatkowych znaczników deklaratywnych lub kodu. Jednak interfejsy BoundField i CheckBoxField nie mają możliwości dostosowywania często potrzebne w rzeczywistych scenariuszach. Aby dostosować edytowalny lub wstawiany interfejs w elementy GridView lub DetailsView, należy zamiast tego użyć pola szablonu.
W poprzednim samouczku pokazano, jak dostosować interfejsy modyfikacji danych przez dodanie kontrolek sieci Web walidacji. W tym samouczku przyjrzymy się, jak dostosować rzeczywiste kontrolki sieci Web zbierania danych, zastępując standardowe kontrolki TextBox i CheckBoxField standardową kontrolką TextBox i CheckBox pola alternatywnymi kontrolkami wejściowymi sieci Web. W szczególności utworzymy edytowalny element GridView, który umożliwia aktualizację nazwy, kategorii, dostawcy i stanu produktu. Podczas edytowania określonego wiersza pola kategorii i dostawcy będą renderowane jako Listy rozwijane, zawierające zestaw dostępnych kategorii i dostawców do wyboru. Ponadto zastąpimy domyślną kontrolkę CheckBoxField kontrolką RadioButtonList, która oferuje dwie opcje: "Aktywne" i "Przerwane".
Rysunek 1. Interfejs edycji kontrolki GridView zawiera listy rozwijane i przyciski radiowe (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Krok 1. Tworzenie odpowiedniegoUpdateProduct
przeciążenia
W tym samouczku utworzymy edytowalny element GridView, który umożliwia edytowanie nazwy, kategorii, dostawcy i stanu produktu. W związku z tym potrzebujemy UpdateProduct
przeciążenia, które akceptuje pięć parametrów wejściowych tych czterech wartości produktu oraz ProductID
. Podobnie jak w poprzednich przeciążeniach, będzie to:
- Pobierz informacje o produkcie z bazy danych dla określonego
ProductID
elementu , ProductName
Aktualizowanie pól ,CategoryID
,SupplierID
iDiscontinued
- Wyślij żądanie aktualizacji do dal za pomocą metody TableAdapter
Update()
.
W przypadku zwięzłości tego konkretnego przeciążenia pominięto sprawdzanie reguły biznesowej, które gwarantuje, że produkt jest oznaczony jako zaprzestany, nie jest jedynym produktem oferowanym przez dostawcę. Możesz go dodać, jeśli wolisz lub, najlepiej, refaktoryzować logikę do oddzielnej metody.
Poniższy kod przedstawia nowe UpdateProduct
przeciążenie w ProductsBLL
klasie:
<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, False)>
Public Function UpdateProduct(
ByVal productName As String, ByVal categoryID As Nullable(Of Integer),
ByVal supplierID As Nullable(Of Integer), ByVal discontinued As Boolean,
ByVal 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 supplierID.HasValue Then
product.SetSupplierIDNull()
Else
product.SupplierID = supplierID.Value
End If
If Not categoryID.HasValue Then
product.SetCategoryIDNull()
Else
product.CategoryID = categoryID.Value
End If
product.Discontinued = discontinued
Dim rowsAffected As Integer = Adapter.Update(product)
Return rowsAffected = 1
End Function
Krok 2. Tworzenie edytowalnego obiektu GridView
UpdateProduct
Po dodaniu przeciążenia możemy utworzyć edytowalny element GridView. CustomizedUI.aspx
Otwórz stronę w folderze EditInsertDelete
i dodaj kontrolkę GridView do projektanta. Następnie utwórz nowy obiekt ObjectDataSource na podstawie tagu inteligentnego GridView. Skonfiguruj obiekt ObjectDataSource, aby pobrać informacje o produkcie za pośrednictwem ProductBLL
metody klasy GetProducts()
i zaktualizować dane produktu przy użyciu właśnie utworzonego UpdateProduct
przeciążenia. Na kartach INSERT i DELETE wybierz pozycję (Brak) z list rozwijanych.
Rysunek 2. Konfigurowanie obiektu ObjectDataSource do używania właśnie utworzonego UpdateProduct
przeciążenia (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Jak pokazano w samouczkach dotyczących modyfikacji danych, składnia deklaratywna dla obiektu ObjectDataSource utworzonego przez program Visual Studio przypisuje OldValuesParameterFormatString
właściwość do original_{0}
elementu . Oczywiście nie będzie to działać z naszą warstwą logiki biznesowej, ponieważ nasze metody nie oczekują przekazania oryginalnej ProductID
wartości. W związku z tym, jak wykonaliśmy w poprzednich samouczkach, pośmiń chwilę, aby usunąć to przypisanie właściwości ze składni deklaratywnej lub, zamiast tego, ustaw wartość tej właściwości na {0}
.
Po tej zmianie znacznik deklaratywny objectDataSource powinien wyglądać następująco:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
UpdateMethod="UpdateProduct">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="discontinued" Type="Boolean" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
</asp:ObjectDataSource>
Należy pamiętać, że OldValuesParameterFormatString
właściwość została usunięta i że istnieje Parameter
element w UpdateParameters
kolekcji dla każdego parametru wejściowego oczekiwanego przez nasze UpdateProduct
przeciążenie.
Podczas gdy obiekt ObjectDataSource jest skonfigurowany do aktualizowania tylko podzestawu wartości produktu, kontrolka GridView obecnie wyświetla wszystkie pola produktu. Pośmiń chwilę na edycję kontrolki GridView, aby:
- Obejmuje tylko pola
ProductName
, ,SupplierName
CategoryName
, BoundFields iDiscontinued
CheckBoxField - Pola
CategoryName
iSupplierName
, które mają pojawić się przed (po lewej stronie)Discontinued
pola CheckBoxField - Właściwość
CategoryName
iSupplierName
BoundFieldsHeaderText
jest ustawiona odpowiednio na "Category" i "Supplier" - Obsługa edycji jest włączona (zaznacz pole wyboru Włącz edytowanie w tagu inteligentnym GridView)
Po tych zmianach projektant będzie wyglądać podobnie do rysunku 3, a składnia deklaratywna kontrolki GridView pokazana poniżej.
Rysunek 3. Usuwanie niepotrzebnych pól z widoku GridView (kliknij, aby wyświetlić obraz pełnowymiarowy)
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True"
SortExpression="SupplierName" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Columns>
</asp:GridView>
W tym momencie działanie kontrolki GridView tylko do odczytu zostało ukończone. Podczas wyświetlania danych każdy produkt jest renderowany jako wiersz w elementy GridView, pokazując nazwę produktu, kategorię, dostawcę i stan przerwania.
Rysunek 4. Interfejs tylko do odczytu kontrolki GridView został ukończony (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Uwaga
Jak opisano w artykule Omówienie wstawiania, aktualizowania i usuwania danych, ważne jest, aby stan widoku gridView był włączony (zachowanie domyślne). Jeśli ustawisz właściwość GridView EnableViewState
na false
wartość , wystąpi ryzyko przypadkowego usunięcia lub edytowania rekordów przez współbieżnych użytkowników.
Krok 3. Używanie listy rozwijanej dla interfejsów edycji kategorii i dostawcy
Pamiętaj, że ProductsRow
obiekt zawiera CategoryID
właściwości , CategoryName
, SupplierID
i SupplierName
, które zapewniają rzeczywiste wartości identyfikatora klucza obcego w Products
tabeli bazy danych oraz odpowiednie Name
wartości w Categories
tabelach i Suppliers
. Wartości ProductRow
i CategoryID
SupplierID
mogą być odczytywane z i zapisywane do, natomiast CategoryName
właściwości i SupplierName
są oznaczone jako tylko do odczytu.
Ze względu na stan CategoryName
tylko do odczytu właściwości i SupplierName
odpowiednie pola ograniczenia mają ustawioną ReadOnly
True
właściwość na , co uniemożliwia modyfikowanie tych wartości podczas edycji wiersza. Chociaż możemy ustawić ReadOnly
właściwość na False
, renderowanie CategoryName
pól i SupplierName
BoundFields jako TextBoxes podczas edycji, takie podejście spowoduje wyjątek, gdy użytkownik próbuje zaktualizować produkt, ponieważ nie UpdateProduct
ma przeciążenia, które pobiera CategoryName
i SupplierName
wprowadza dane wejściowe. W rzeczywistości nie chcemy tworzyć takiego przeciążenia z dwóch powodów:
- Tabela
Products
nie maSupplierName
aniCategoryName
pól, aleSupplierID
iCategoryID
. W związku z tym chcemy, aby nasza metoda została przekazana tych konkretnych wartości identyfikatorów, a nie ich wartości tabel odnośników. - Wymaganie od użytkownika wpisania nazwy dostawcy lub kategorii jest mniejsze niż idealne, ponieważ wymaga od użytkownika znajomości dostępnych kategorii i dostawców oraz ich poprawnych pisowni.
Pola dostawca i kategoria powinny wyświetlać nazwy kategorii i dostawców w trybie tylko do odczytu (tak jak teraz) oraz listę rozwijaną odpowiednich opcji podczas edycji. Korzystając z listy rozwijanej, użytkownik końcowy może szybko zobaczyć, jakie kategorie i dostawcy są dostępne do wyboru, i może łatwiej dokonać wyboru.
Aby zapewnić to zachowanie, musimy przekonwertować wartości SupplierName
i BoundFields na TemplateFields, których ItemTemplate
emituje SupplierName
wartości i CategoryName
i, których EditItemTemplate
używa kontrolki DropDownList, aby wyświetlić listę dostępnych kategorii i CategoryName
dostawców.
Dodawanie listCategories
rozwijanych iSuppliers
Zacznij od przekonwertowania pól SupplierName
i CategoryName
BoundFields na Pola szablonów, klikając link Edytuj kolumny z tagu inteligentnego GridView, wybierając pole BoundField z listy w lewym dolnym rogu, a następnie klikając link "Konwertuj to pole na pole szablonu". Proces konwersji utworzy pole szablonu z wartością ItemTemplate
i EditItemTemplate
, jak pokazano w poniższej składni deklaratywnej:
<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
<EditItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("CategoryName") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("CategoryName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Ponieważ pole BoundField zostało oznaczone jako tylko do odczytu, zarówno ItemTemplate
kontrolka i EditItemTemplate
zawiera kontrolkę sieci Web Etykieta, której Text
właściwość jest powiązana z odpowiednim polem danych (CategoryName
w składni powyżej). Musimy zmodyfikować kontrolkę , zastępując kontrolkę Etykieta EditItemTemplate
internetowa kontrolką DropDownList.
Jak widzieliśmy w poprzednich samouczkach, szablon można edytować za pomocą projektanta lub bezpośrednio ze składni deklaratywnej. Aby edytować go za pomocą projektanta, kliknij link Edytuj szablony z tagu inteligentnego GridView i wybierz pracę z polem EditItemTemplate
Kategoria . Usuń kontrolkę Etykieta sieci Web i zastąp ją kontrolką DropDownList, ustawiając właściwość Identyfikator listy Rozwijanej na Categories
wartość .
Rysunek 5. Usuwanie pola TexBox i dodawanie listy rozwijanej do EditItemTemplate
listy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Następnie musimy wypełnić listę DropDownList dostępnymi kategoriami. Kliknij link Wybierz źródło danych z tagu inteligentnego Listy rozwijanej i wybierz opcję utworzenia nowego obiektu ObjectDataSource o nazwie CategoriesDataSource
.
Rysunek 6. Tworzenie nowej kontrolki ObjectDataSource o nazwie CategoriesDataSource
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Aby obiekt ObjectDataSource zwrócił wszystkie kategorie, powiąż go z CategoriesBLL
metodą klasy GetCategories()
.
Rysunek 7. Powiązanie obiektu ObjectDataSource z CategoriesBLL
metodą "s GetCategories()
" (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Na koniec skonfiguruj ustawienia listy rozwijanej, tak aby CategoryName
pole było wyświetlane w każdej liście rozwijanej z ListItem
CategoryID
polem używanym jako wartość.
Rysunek 8. Wyświetlanie CategoryName
pola i CategoryID
używane jako wartość (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po wprowadzeniu tych zmian znaczniki deklaratywne dla EditItemTemplate
elementu w CategoryName
polu TemplateField będą zawierać zarówno listę rozwijaną, jak i obiekt ObjectDataSource:
<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
<EditItemTemplate>
<asp:DropDownList ID="Categories" runat="server"
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName" DataValueField="CategoryID">
</asp:DropDownList>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("CategoryName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Uwaga
Lista rozwijana na EditItemTemplate
liście musi mieć włączony stan widoku. Wkrótce dodamy składnię powiązania danych do deklaratywnej składni listy DropDownList i poleceń powiązania danych, takich jak Eval()
i Bind()
mogą być wyświetlane tylko w kontrolkach, których stan widoku jest włączony.
Powtórz te kroki, aby dodać listę DropDownList o nazwie Suppliers
do pola szablonu EditItemTemplate
SupplierName
. Spowoduje to dodanie listy rozwijanej EditItemTemplate
do obiektu i utworzenie innego obiektu ObjectDataSource. Obiekt Suppliers
ObjectDataSource listy DropDownList należy jednak skonfigurować tak, aby wywoływać SuppliersBLL
metodę klasy GetSuppliers()
. Ponadto skonfiguruj listę Suppliers
DropDownList, aby wyświetlić CompanyName
pole i użyć SupplierID
pola jako wartości jego ListItem
wartości.
Po dodaniu listy DropDownLists do tych dwóch EditItemTemplate
elementów załaduj stronę w przeglądarce i kliknij przycisk Edytuj dla produktu Chef Anton's Cajun Seasoning. Jak pokazano na rysunku 9, kolumny kategorii i dostawcy produktu są renderowane jako listy rozwijane zawierające dostępne kategorie i dostawców do wyboru. Należy jednak pamiętać, że pierwsze elementy na obu listach rozwijanych są wybierane domyślnie (Napoje dla kategorii i Egzotyczne płyny jako dostawca), mimo że Chef Anton's Cajun Seasoning jest condiment dostarczony przez New Orleans Cajun Delights.
Rysunek 9. Pierwszy element na listach rozwijanych jest domyślnie wybierany (kliknij, aby wyświetlić obraz pełnowymiarowy)
Ponadto po kliknięciu przycisku Aktualizuj zobaczysz, że wartości CategoryID
i SupplierID
produktu są ustawione na NULL
wartość . Oba te niepożądane zachowania są spowodowane, ponieważ listy rozwijane w s EditItemTemplate
nie są powiązane z żadnymi polami danych z danych źródłowych produktów.
Wiązanie list rozwijanych z polamiCategoryID
danych iSupplierID
Aby edytować listę rozwijaną kategorii i dostawcy produktu ustawioną na odpowiednie wartości i aby te wartości były wysyłane z powrotem do metody BLL UpdateProduct
po kliknięciu pozycji Aktualizuj, musimy powiązać właściwości CategoryID
Listy rozwijane SelectedValue
z polami danych i SupplierID
przy użyciu dwukierunkowego powiązania danych. Aby to osiągnąć za pomocą listy Categories
DropDownList, możesz dodać SelectedValue='<%# Bind("CategoryID") %>'
ją bezpośrednio do składni deklaratywnej.
Alternatywnie można ustawić powiązania danych listy DropDownList, edytując szablon za pomocą Projektanta i klikając link Edytuj elementy DataBindings z tagu inteligentnego Listy rozwijanej. Następnie wskaż, że SelectedValue
właściwość powinna być powiązana z CategoryID
polem przy użyciu dwukierunkowego powiązania danych (zobacz Rysunek 10). Powtórz proces deklaratywny lub Projektant, aby powiązać SupplierID
pole danych z listą rozwijaną Suppliers
.
Rysunek 10. Powiązanie CategoryID
właściwości listy rozwijanej z SelectedValue
dwukierunkowym powiązaniem danych (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po zastosowaniu powiązań do SelectedValue
właściwości dwóch list rozwijanych edytowane kolumny kategorii i dostawcy produktu będą domyślnie domyślnie wartościami bieżącego produktu. Po kliknięciu przycisku Aktualizuj CategoryID
wartości i SupplierID
wybranego elementu listy rozwijanej zostaną przekazane do UpdateProduct
metody . Rysunek 11 przedstawia samouczek po dodaniu instrukcji powiązania danych; Zwróć uwagę, jak wybrane elementy listy rozwijanej dla Chef Anton's Cajun Seasoning są poprawnie Condiment i New Orleans Cajun Delights.
Rysunek 11. Edytowana kategoria i wartości dostawców produktu są domyślnie wybrane (kliknij, aby wyświetlić obraz pełnowymiarowy)
ObsługaNULL
wartości
Kolumny CategoryID
i SupplierID
w Products
tabeli mogą mieć NULL
wartość , ale listy rozwijane w EditItemTemplate
tabeli nie zawierają elementu listy do reprezentowania NULL
wartości. Ma to dwie konsekwencje:
- Użytkownik nie może użyć naszego interfejsu, aby zmienić kategorię lub dostawcę produktu z wartości innej
NULL
niż wartość naNULL
- Jeśli produkt ma wartość
NULL
CategoryID
lubSupplierID
, kliknięcie przycisku Edytuj spowoduje wyjątek. Jest to spowodowane tym, żeNULL
wartość zwracana przezCategoryID
wartość (lubSupplierID
) wBind()
instrukcji nie jest mapowana na wartość w liście DropDownList (Lista rozwijana zgłasza wyjątek, gdy jegoSelectedValue
właściwość jest ustawiona na wartość nie w kolekcji elementów listy).
Aby obsługiwać NULL
CategoryID
wartości i SupplierID
obsługiwać wartości, musimy dodać kolejny ListItem
element do każdej listy Rozwijanej, aby reprezentować NULL
wartość. W samouczku Master/Detail Filtering With a DropDownList (Filtrowanie wzorca/szczegółów za pomocą listy rozwijanej DropDownList) zobaczyliśmy, jak dodać dodatkowy element ListItem
do listy rozwijanej danych, który obejmował ustawienie właściwości DropDownList AppendDataBoundItems
na True
wartość i ręczne dodanie dodatkowego ListItem
elementu . W tym poprzednim samouczku dodaliśmy jednak element ListItem
z wartością Value
-1
. Logika powiązania danych w ASP.NET jednak automatycznie konwertuje pusty ciąg na NULL
wartość i odwrotnie. W związku z tym na potrzeby tego samouczka ListItem
chcemy, aby ciąg był Value
pusty.
Zacznij od ustawienia właściwości DropDownLists AppendDataBoundItems
na True
wartość . Następnie dodaj element NULL
ListItem
, dodając następujący <asp:ListItem>
element do każdej listy Rozwijanej, tak aby znacznik deklaratywny wyglądał następująco:
<asp:DropDownList ID="Categories" runat="server"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'
AppendDataBoundItems="True">
<asp:ListItem Value="">(None)</asp:ListItem>
</asp:DropDownList>
Wybrano opcję użycia wartości "(None)" jako wartości Text dla tego ListItem
elementu , ale można ją zmienić tak, aby była również pustym ciągiem, jeśli chcesz.
Uwaga
Jak pokazano w samouczku Master/Detail Filtering With a DropDownList ( ListItem
Filtrowanie wzorca/szczegółów z listą rozwijaną) można dodać do listy rozwijanej za pośrednictwem Projektanta, klikając właściwość DropDownList Items
w okno Właściwości (która będzie wyświetlać ListItem
Edytor kolekcji). Pamiętaj jednak, aby dodać element do tego samouczka NULL
ListItem
za pomocą składni deklaratywnej. Jeśli używasz Edytora ListItem
kolekcji, wygenerowana składnia deklaratywna całkowicie pominą Value
ustawienie po przypisaniu pustego ciągu, tworząc znacznik deklaratywny, taki jak: <asp:ListItem>(None)</asp:ListItem>
. Chociaż może to wyglądać nieszkodliwie, brakująca wartość powoduje, że lista DropDownList używa Text
wartości właściwości w swoim miejscu. Oznacza to, że w przypadku wybrania tej NULL
ListItem
wartości zostanie podjęta próba przypisania CategoryID
wartości "(None)", co spowoduje wyjątek. Jawnie ustawiając Value=""
wartość NULL
, zostanie przypisana do CategoryID
wartości po wybraniu elementu NULL
ListItem
.
Powtórz te kroki dla listy rozwijanej Dostawcy.
Dzięki temu dodatkowemu ListItem
interfejsowi edycji można teraz przypisywać NULL
wartości do pól i SupplierID
produktuCategoryID
, jak pokazano na rysunku 12.
Rysunek 12. Wybierz pozycję (Brak), aby przypisać NULL
wartość dla kategorii lub dostawcy produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 4. Używanie przycisków radiowych dla stanu przerwanego
Obecnie pole danych produktów Discontinued
jest wyrażane przy użyciu pola CheckBoxField, które renderuje wyłączone pole wyboru dla wierszy tylko do odczytu i włączone pole wyboru dla edytowanego wiersza. Chociaż ten interfejs użytkownika jest często odpowiedni, możemy dostosować go w razie potrzeby przy użyciu pola szablonu. W tym samouczku zmieńmy pole CheckBoxField na pole szablonu, które używa kontrolki RadioButtonList z dwiema opcjami "Aktywne" i "Przerwane", z których użytkownik może określić wartość produktu Discontinued
.
Zacznij od przekonwertowania pola Discontinued
CheckBoxField na pole szablonu, które spowoduje utworzenie pola szablonu z elementem ItemTemplate
i EditItemTemplate
. Oba szablony obejmują pole CheckBox z właściwością Checked
powiązaną Discontinued
z polem danych. Jedyną różnicą między nimi jest to, że ItemTemplate
właściwość CheckBox jest ustawiona Enabled
na False
wartość .
Zastąp pole wyboru zarówno w kontrolce , jak ItemTemplate
i EditItemTemplate
kontrolką RadioButtonList, ustawiając właściwości elementu RadioButtonLists ID
na DiscontinuedChoice
wartość . Następnie należy wskazać, że kolumny RadioButtonLists powinny zawierać dwa przyciski radiowe, z jedną oznaczoną etykietą "Active" z wartością "False" i jedną oznaczoną etykietą "Discontinued" z wartością "True". Aby to osiągnąć, możesz wprowadzić <asp:ListItem>
elementy bezpośrednio za pomocą składni deklaratywnej lub użyć ListItem
Edytora kolekcji w Projektancie. Rysunek 13 przedstawia ListItem
Edytor kolekcji po określeniu dwóch opcji przycisku radiowego.
Rysunek 13. Dodawanie opcji aktywnych i nieaktywnych do listy RadioButtonList (kliknij, aby wyświetlić obraz pełnowymiarowy)
Ponieważ właściwość RadioButtonList w elemecie ItemTemplate
nie powinna być edytowalna, ustaw jej Enabled
właściwość na False
, pozostawiając Enabled
właściwość na True
(wartość domyślną) dla elementu RadioButtonList w obiekcie EditItemTemplate
. Spowoduje to ustawienie przycisków radiowych w wierszu nieedytowany jako tylko do odczytu, ale umożliwi użytkownikowi zmianę wartości RadioButton dla edytowanego wiersza.
Nadal musimy przypisać właściwości kontrolek SelectedValue
RadioButtonList, aby odpowiedni przycisk radiowy był wybierany na podstawie pola danych produktu Discontinued
. Podobnie jak w przypadku elementów DropDownLists, które zostały zbadane wcześniej w tym samouczku, składnia powiązania danych może zostać dodana bezpośrednio do tagów deklaratywnych lub za pośrednictwem linku Edit DataBindings w tagach inteligentnych RadioButtonLists.
Po dodaniu dwóch elementów RadioButtonLists i skonfigurowaniu ich Discontinued
znacznik deklaratywny TemplateField powinien wyglądać następująco:
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<asp:RadioButtonList ID="DiscontinuedChoice" runat="server"
Enabled="False" SelectedValue='<%# Bind("Discontinued") %>'>
<asp:ListItem Value="False">Active</asp:ListItem>
<asp:ListItem Value="True">Discontinued</asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
<EditItemTemplate>
<asp:RadioButtonList ID="DiscontinuedChoice" runat="server"
SelectedValue='<%# Bind("Discontinued") %>'>
<asp:ListItem Value="False">Active</asp:ListItem>
<asp:ListItem Value="True">Discontinued</asp:ListItem>
</asp:RadioButtonList>
</EditItemTemplate>
</asp:TemplateField>
Dzięki tym zmianom kolumna Discontinued
została przekształcona z listy pól wyboru na listę par przycisków radiowych (zobacz Rysunek 14). Podczas edytowania produktu wybrany jest odpowiedni przycisk radiowy, a stan produktu nieumyślnie jest aktualizowany, wybierając inny przycisk radiowy i klikając przycisk Aktualizuj.
Rysunek 14. Wycofane pola wyboru zostały zastąpione przez pary przycisków radiowych (kliknij, aby wyświetlić obraz pełnowymiarowy)
Uwaga
Ponieważ kolumna Discontinued
w Products
bazie danych nie może zawierać NULL
wartości, nie musimy martwić się o przechwytywanie NULL
informacji w interfejsie. Jeśli jednak kolumna może zawierać NULL
wartości, Discontinued
chcemy dodać trzeci przycisk radiowy do listy z ustawionym Value
pustym ciągiem (Value=""
), podobnie jak w przypadku kategorii i listy rozwijanej dostawcy.
Podsumowanie
Mimo że interfejsy BoundField i CheckBoxField automatycznie renderują interfejsy tylko do odczytu, edytowania i wstawiania, nie mają możliwości dostosowywania. Często jednak musimy dostosować interfejs edytowania lub wstawiania, być może dodanie kontrolek weryfikacji (jak pokazano w poprzednim samouczku) lub dostosowanie interfejsu użytkownika zbierania danych (jak pokazano w tym samouczku). Dostosowywanie interfejsu za pomocą pola TemplateField można podsumować w następujących krokach:
- Dodawanie pola szablonu lub konwertowanie istniejącego pola BoundField lub CheckBoxField na pole szablonu
- Rozszerzanie interfejsu zgodnie z potrzebami
- Wiązanie odpowiednich pól danych z nowo dodanymi kontrolkami sieci Web przy użyciu dwukierunkowego powiązania danych
Oprócz używania wbudowanych kontrolek ASP.NET Sieci Web można również dostosować szablony pola szablonów z niestandardowymi, skompilowanymi kontrolkami serwera i kontrolkami użytkownika.
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.