Dostosowywanie interfejsu edycji kontrolki DataList (C#)
Autor: Scott Mitchell
W tym samouczku utworzymy bogatszy interfejs edycji dla elementu DataList, który zawiera listy rozwijane i pole wyboru.
Wprowadzenie
Kontrolki znaczników i sieci Web w kontrolce DataList EditItemTemplate
definiują swój interfejs edytowalny. We wszystkich edytowalnych przykładach usługi DataList, które omówiliśmy do tej pory, interfejs edytowalny składa się z kontrolek sieci Web TextBox. W poprzednim samouczku ulepszyliśmy środowisko użytkownika czasu edycji przez dodanie kontrolek weryfikacji.
Można EditItemTemplate
go dodatkowo rozszerzyć, aby uwzględnić kontrolki sieci Web inne niż TextBox, takie jak Listy rozwijane, RadioButtonLists, Kalendarze itd. Podobnie jak w przypadku elementów TextBoxes podczas dostosowywania interfejsu edycji w celu uwzględnienia innych kontrolek sieci Web, wykonaj następujące czynności:
- Dodaj kontrolkę Sieć Web do elementu
EditItemTemplate
. - Użyj składni powiązania danych, aby przypisać odpowiednią wartość pola danych do odpowiedniej właściwości.
- W procedurze obsługi zdarzeń
UpdateCommand
programowo uzyskaj dostęp do wartości kontrolki sieci Web i przekaż ją do odpowiedniej metody BLL.
W tym samouczku utworzymy bogatszy interfejs edycji dla elementu DataList, który zawiera listy rozwijane i pole wyboru. W szczególności utworzymy listę danych DataList, która wyświetla informacje o produkcie i zezwala na aktualizowanie nazwy produktu, dostawcy, kategorii i stanu zaprzestania (zobacz Rysunek 1).
Rysunek 1. Interfejs edycji zawiera pole tekstowe, dwie listy rozwijane i pole wyboru (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Krok 1. Wyświetlanie informacji o produkcie
Przed utworzeniem interfejsu edytowalnego elementu DataList należy najpierw skompilować interfejs tylko do odczytu. Zacznij od otwarcia CustomizedUI.aspx
strony z EditDeleteDataList
folderu, a następnie w Projektancie dodaj do strony element DataList, ustawiając jej ID
właściwość na Products
. Na podstawie tagu inteligentnego DataList utwórz nowy obiekt ObjectDataSource. Nadaj temu nowemu identyfikatorowi ObjectDataSource ProductsDataSource
nazwę i skonfiguruj ją tak, aby pobierała dane z ProductsBLL
metody klasy s GetProducts
. Podobnie jak w przypadku poprzednich edytowalnych samouczków DataList, zaktualizujemy edytowane informacje o produkcie, przechodząc bezpośrednio do warstwy logiki biznesowej. W związku z tym ustaw listy rozwijane na kartach UPDATE, INSERT i DELETE na wartość (Brak).
Rysunek 2. Ustawianie list rozwijanych UPDATE, INSERT i DELETE na wartość (Brak) (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po skonfigurowaniu obiektu ObjectDataSource program Visual Studio utworzy wartość domyślną ItemTemplate
dla elementu DataList, który wyświetla listę nazw i wartości dla każdego zwracanego pola danych. Zmodyfikuj ItemTemplate
element tak, aby szablon wyświetlał nazwę produktu w <h4>
elemecie wraz z nazwą kategorii, nazwą dostawcy, ceną i stanem przerwania. Ponadto dodaj przycisk Edytuj, upewniając się, że jego CommandName
właściwość jest ustawiona na Edytuj. Adiustacja deklaratywna dla mojego ItemTemplate
następującego:
<ItemTemplate>
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Eval("ProductName") %>' />
</h4>
<table border="0">
<tr>
<td class="ProductPropertyLabel">Category:</td>
<td class="ProductPropertyValue">
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Eval("CategoryName") %>' />
</td>
<td class="ProductPropertyLabel">Supplier:</td>
<td class="ProductPropertyValue">
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Eval("SupplierName") %>' />
</td>
</tr>
<tr>
<td class="ProductPropertyLabel">Discontinued:</td>
<td class="ProductPropertyValue">
<asp:Label ID="DiscontinuedLabel" runat="server"
Text='<%# Eval("Discontinued") %>' />
</td>
<td class="ProductPropertyLabel">Price:</td>
<td class="ProductPropertyValue">
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
</td>
</tr>
<tr>
<td colspan="4">
<asp:Button runat="Server" ID="EditButton"
Text="Edit" CommandName="Edit" />
</td>
</tr>
</table>
<br />
</ItemTemplate>
Powyższy znacznik określa informacje o produkcie przy użyciu <nagłówka h4> dla nazwy produktu i czterech kolumn <table>
dla pozostałych pól. Klasy ProductPropertyLabel
i ProductPropertyValue
CSS zdefiniowane w programie Styles.css
zostały omówione w poprzednich samouczkach. Rysunek 3 przedstawia postęp wyświetlania za pośrednictwem przeglądarki.
Rysunek 3. Wyświetlana jest nazwa, dostawca, kategoria, stan przerwany i cena każdego produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 2. Dodawanie kontrolek sieci Web do interfejsu edycji
Pierwszym krokiem tworzenia dostosowanego interfejsu edycji DataList jest dodanie wymaganych kontrolek sieci Web do elementu EditItemTemplate
. W szczególności potrzebujemy listy rozwijanej dla kategorii, innej dla dostawcy i pola kontrolnego dla stanu przerwania działania. Ponieważ cena produktu nie jest edytowalna w tym przykładzie, możemy kontynuować jego wyświetlanie przy użyciu kontrolki Etykieta w sieci Web.
Aby dostosować interfejs edycji, kliknij link Edytuj szablony z tagu inteligentnego DataList i wybierz EditItemTemplate
opcję z listy rozwijanej. Dodaj listę DropDownList do elementu EditItemTemplate
i ustaw jej ID
wartość na Categories
.
Rysunek 4. Dodawanie listy rozwijanej dla kategorii (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Następnie z tagu inteligentnego DropDownList wybierz opcję Wybierz źródło danych i utwórz nowy obiekt ObjectDataSource o nazwie CategoriesDataSource
. Skonfiguruj tę wartość ObjectDataSource, aby użyć CategoriesBLL
metody klasy s GetCategories()
(zobacz Rysunek 5). Następnie Kreator konfiguracji źródła danych Listy rozwijanej wyświetli monit o użycie pól danych dla poszczególnych ListItem
właściwości Text
i Value
. Lista rozwijana Wyświetl CategoryName
pole danych i użyj CategoryID
wartości jako wartości, jak pokazano na rysunku 6.
Rysunek 5. Tworzenie nowego obiektuDataSource o nazwie CategoriesDataSource
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Rysunek 6. Konfigurowanie pól wyświetlania i wartości listy rozwijanej (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Powtórz tę serię kroków, aby utworzyć listę DropDownList dla dostawców. Dla tej listy rozwijanej ID
Suppliers
ustaw wartość i nadaj jej nazwę ObjectDataSource SuppliersDataSource
.
Po dodaniu dwóch list DropDownLists dodaj pole wyboru dla stanu przerwanego i pole tekstowe dla nazwy produktu. Ustaw wartości ID
s dla pola CheckBox i TextBox odpowiednio na Discontinued
i ProductName
. Dodaj element RequiredFieldValidator, aby upewnić się, że użytkownik podaje wartość nazwy produktu.
Na koniec dodaj przyciski Aktualizuj i Anuluj. Należy pamiętać, że w przypadku tych dwóch przycisków należy odpowiednio ustawić ich CommandName
właściwości na Wartość Aktualizuj i Anuluj.
Możesz położyć interfejs edycji, jak chcesz. Zdecydowałem się użyć tego samego układu czterech kolumn <table>
z interfejsu tylko do odczytu, jak pokazano następującą składnię deklaratywną i zrzut ekranu:
<EditItemTemplate>
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Eval("ProductName") %>' />
</h4>
<table border="0">
<tr>
<td class="ProductPropertyLabel">Name:</td>
<td colspan="3" class="ProductPropertyValue">
<asp:TextBox runat="server" ID="ProductName" Width="90%" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName"
ErrorMessage="You must enter a name for the product."
runat="server">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td class="ProductPropertyLabel">Category:</td>
<td class="ProductPropertyValue">
<asp:DropDownList ID="Categories" runat="server"
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName" DataValueField="CategoryID" />
</td>
<td class="ProductPropertyLabel">Supplier:</td>
<td class="ProductPropertyValue">
<asp:DropDownList ID="Suppliers" DataTextField="CompanyName"
DataSourceID="SuppliersDataSource"
DataValueField="SupplierID" runat="server" />
</td>
</tr>
<tr>
<td class="ProductPropertyLabel">Discontinued:</td>
<td class="ProductPropertyValue">
<asp:CheckBox runat="server" id="Discontinued" />
</td>
<td class="ProductPropertyLabel">Price:</td>
<td class="ProductPropertyValue">
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>' />
</td>
</tr>
<tr>
<td colspan="4">
<asp:Button runat="Server" ID="UpdateButton" CommandName="Update"
Text="Update" />
<asp:Button runat="Server" ID="CancelButton" CommandName="Cancel"
Text="Cancel" CausesValidation="False" />
</td>
</tr>
</table>
<br />
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategories"
TypeName="CategoriesBLL">
</asp:ObjectDataSource>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetSuppliers"
TypeName="SuppliersBLL">
</asp:ObjectDataSource>
</EditItemTemplate>
Rysunek 7. Interfejs edycji jest ułożony jak interfejs tylko do odczytu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 3. Tworzenie programów obsługi zdarzeń EditCommand i CancelCommand
Obecnie w obiekcie nie ma składni EditItemTemplate
powiązania danych (z wyjątkiem UnitPriceLabel
elementu , który został skopiowany z elementu ItemTemplate
). Na chwilę dodamy składnię powiązania danych, ale najpierw utworzymy programy obsługi zdarzeń dla zdarzeń i CancelCommand
zdarzeń DataListEditCommand
. Pamiętaj, że obowiązkiem EditCommand
programu obsługi zdarzeń jest renderowanie interfejsu edycji elementu DataList, którego przycisk Edytuj został kliknięty, natomiast CancelCommand
zadaniem zadania jest zwrócenie elementu DataList do stanu wstępnego edytowania.
Utwórz te dwa programy obsługi zdarzeń i użyj następującego kodu:
protected void Products_EditCommand(object source, DataListCommandEventArgs e)
{
// Set the DataList's EditItemIndex property and rebind the data
Products.EditItemIndex = e.Item.ItemIndex;
Products.DataBind();
}
protected void Products_CancelCommand(object source, DataListCommandEventArgs e)
{
// Return to DataList to its pre-editing state
Products.EditItemIndex = -1;
Products.DataBind();
}
Po wprowadzeniu tych dwóch programów obsługi zdarzeń kliknięcie przycisku Edytuj powoduje wyświetlenie interfejsu edycji i kliknięcie przycisku Anuluj zwraca edytowany element do trybu tylko do odczytu. Rysunek 8 przedstawia element DataList po kliknięciu przycisku Edytuj dla narzędzia Chef Anton s Gumbo Mix. Ponieważ jeszcze dodaliśmy dowolną składnię powiązania danych do interfejsu edycji, ProductName
pole TextBox jest puste, Discontinued
pole wyboru niezaznaczone i pierwsze elementy wybrane z listy rozwijanej Categories
i Suppliers
.
Rysunek 8. Kliknięcie przycisku Edytuj wyświetla interfejs edycji (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Krok 4. Dodawanie składni DataBinding do interfejsu edycji
Aby interfejs edycji wyświetlał bieżące wartości produktu, musimy użyć składni powiązania danych, aby przypisać wartości pól danych do odpowiednich wartości kontrolki sieci Web. Składnię powiązania danych można zastosować za pomocą projektanta, przechodząc do ekranu Edytowanie szablonów i wybierając link Edytuj daneBindings z tagów inteligentnych kontrolek sieci Web. Alternatywnie składnia powiązania danych można dodać bezpośrednio do znaczników deklaratywnych.
ProductName
Przypisz wartość pola danych do ProductName
właściwości TextBoxText
, CategoryID
wartości pól danych i SupplierID
do Categories
właściwości i Suppliers
DropDownLists SelectedValue
oraz Discontinued
wartości pola danych do Discontinued
właściwości CheckBox sChecked
. Po wprowadzeniu tych zmian za pośrednictwem Projektanta lub bezpośrednio za pomocą znaczników deklaratywnego ponownie przejdź do strony za pośrednictwem przeglądarki i kliknij przycisk Edytuj dla programu Chef Anton s Gumbo Mix. Jak pokazano na rysunku 9, składnia powiązania danych dodała bieżące wartości do pola TextBox, DropDownLists i CheckBox.
Rysunek 9. Kliknięcie przycisku Edytuj wyświetla interfejs edycji (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Krok 5. Zapisywanie zmian użytkownika w programie obsługi zdarzeń UpdateCommand
Gdy użytkownik edytuje produkt i kliknie przycisk Aktualizuj, nastąpi powrót, a zdarzenie DataList zostanie UpdateCommand
wyzwolony. W programie obsługi zdarzeń musimy odczytać wartości z kontrolek sieci Web w kontrolce EditItemTemplate
i za pomocą usługi BLL, aby zaktualizować produkt w bazie danych. Jak widzieliśmy w poprzednich samouczkach, ProductID
zaktualizowany produkt jest dostępny za pośrednictwem kolekcji DataKeys
. Dostęp do pól wprowadzonych przez użytkownika uzyskuje się programowo, odwołując się do kontrolek sieci Web przy użyciu polecenia FindControl("controlID")
, jak pokazano w poniższym kodzie:
protected void Products_UpdateCommand(object source, DataListCommandEventArgs e)
{
// Make sure the page is valid...
if (!Page.IsValid)
return;
// Read in the ProductID from the DataKeys collection
int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]);
// Read in the product name and price values
TextBox productName = (TextBox)e.Item.FindControl("ProductName");
DropDownList categories = (DropDownList)e.Item.FindControl("Categories");
DropDownList suppliers = (DropDownList)e.Item.FindControl("Suppliers");
CheckBox discontinued = (CheckBox)e.Item.FindControl("Discontinued");
string productNameValue = null;
if (productName.Text.Trim().Length > 0)
productNameValue = productName.Text.Trim();
int categoryIDValue = Convert.ToInt32(categories.SelectedValue);
int supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);
bool discontinuedValue = discontinued.Checked;
// Call the ProductsBLL's UpdateProduct method...
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue,
discontinuedValue, productID);
// Revert the DataList back to its pre-editing state
Products.EditItemIndex = -1;
Products.DataBind();
}
Kod rozpoczyna się od konsultacji z właściwością Page.IsValid
, aby upewnić się, że wszystkie kontrolki weryfikacji na stronie są prawidłowe. Jeśli Page.IsValid
parametr to True
, edytowana wartość produktu ProductID
jest odczytywana z DataKeys
kolekcji, a kontrolki sieci Web wpisu danych w elemencie EditItemTemplate
są programowo przywoływane. Następnie wartości z tych kontrolek sieci Web są odczytywane do zmiennych, które następnie są przekazywane do odpowiedniego UpdateProduct
przeciążenia. Po zaktualizowaniu danych lista DataList jest zwracana do stanu wstępnego edytowania.
Uwaga
Pominięto logikę obsługi wyjątków dodaną w samouczku Obsługa wyjątków BLL i DAL-Level Exceptions w celu zachowania kodu i tego przykładu. W ramach ćwiczenia dodaj tę funkcję po ukończeniu tego samouczka.
Krok 6. Obsługa wartości NULL CategoryID i SupplierID
Baza danych Northwind umożliwia używanie NULL
wartości dla Products
tabel CategoryID
i SupplierID
kolumn. Jednak nasz interfejs edycji nie obsługuje NULL
obecnie wartości. Jeśli spróbujemy edytować produkt, który ma NULL
wartość dla kolumn CategoryID
lub SupplierID
, otrzymamy ArgumentOutOfRangeException
komunikat o błędzie podobny do: "Kategorie" ma wartość SelectedValue, która jest nieprawidłowa, ponieważ nie istnieje na liście elementów. Ponadto obecnie nie ma możliwości zmiany kategorii produktu lub wartości dostawcy z wartości innejNULL
niż wartość na jedną NULL
.
Aby obsługiwać NULL
wartości kategorii i listy rozwijane dostawcy, musimy dodać dodatkowy ListItem
element . Wybrano opcję użycia (Brak) jako Text
wartości dla tego ListItem
elementu , ale możesz zmienić ją na coś innego (na przykład pusty ciąg), jeśli chcesz. Na koniec pamiętaj, aby ustawić wartości DropDownLists AppendDataBoundItems
na True
; jeśli zapomnisz to zrobić, kategorie i dostawcy powiązane z listą DropDownList zastąpią statycznie dodany ListItem
element .
Po wprowadzeniu tych zmian znacznik DropDownLists w znaczników DataList EditItemTemplate
powinien wyglądać podobnie do następującego:
<asp:DropDownList ID="Categories" DataSourceID="CategoriesDataSource"
DataTextField="CategoryName" DataValueField="CategoryID" runat="server"
SelectedValue='<%# Eval("CategoryID") %>' AppendDataBoundItems="True">
<asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>
...
<asp:DropDownList ID="Suppliers" DataSourceID="SuppliersDataSource"
DataTextField="CompanyName" DataValueField="SupplierID" runat="server"
SelectedValue='<%# Eval("SupplierID") %>' AppendDataBoundItems="True">
<asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>
Uwaga
Statyczne ListItem
s można dodać do listy rozwijanej za pośrednictwem projektanta lub bezpośrednio za pomocą składni deklaratywnej. Podczas dodawania elementu DropDownList do reprezentowania wartości bazy danych NULL
pamiętaj, aby dodać ListItem
element za pomocą składni deklaratywnej. Jeśli używasz ListItem
Edytora kolekcji w projektancie, 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ące Value
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 (Brak) zostanie podjęta próba przypisania do pola danych produktu (CategoryID
lub SupplierID
, w tym samouczku), co spowoduje wyjątek. Jawne ustawienie powoduje Value=""
NULL
przypisanie wartości do pola danych produktu po wybraniu NULL
ListItem
elementu .
Pośmiń chwilę, aby wyświetlić postęp w przeglądarce. Podczas edytowania produktu zwróć uwagę, że obie Categories
listy rozwijane mają Suppliers
opcję (Brak) na początku listy Rozwijanej.
Rysunek 10. Listy Categories
rozwijane i Suppliers
obejmują opcję (Brak) (Kliknij, aby wyświetlić obraz pełnowymiarowy)
Aby zapisać opcję (Brak) jako wartość bazy danych NULL
, musimy wrócić do programu obsługi zdarzeń UpdateCommand
. Zmień zmienne i supplierIDValue
takcategoryIDValue
, aby były liczbą całkowitą dopuszczaną do wartości null, i przypisz im wartość inną niż Nothing
tylko wtedy, gdy lista DropDownList SelectedValue
nie jest pustym ciągiem:
int? categoryIDValue = null;
if (!string.IsNullOrEmpty(categories.SelectedValue))
categoryIDValue = Convert.ToInt32(categories.SelectedValue);
int? supplierIDValue = null;
if (!string.IsNullOrEmpty(suppliers.SelectedValue))
supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);
Dzięki tej zmianie wartość Nothing
wartości zostanie przekazana do UpdateProduct
metody BLL, jeśli użytkownik wybrał opcję (Brak) z jednej z list rozwijanych, która odpowiada NULL
wartości bazy danych.
Podsumowanie
W tym samouczku pokazano, jak utworzyć bardziej złożony interfejs edycji DataList, który obejmował trzy różne wejściowe kontrolki sieci Web kontrolki TextBox, dwie listy Rozwijane i CheckBox wraz z kontrolkami walidacji. Podczas tworzenia interfejsu edycji kroki są takie same niezależnie od używanych kontrolek sieci Web: zacznij od dodania kontrolek sieci Web do kontrolki DataList s EditItemTemplate
; użyj składni powiązania danych, aby przypisać odpowiednie wartości pól danych z odpowiednimi właściwościami kontrolki sieci Web; a w UpdateCommand
procedurze obsługi zdarzeń programowo uzyskać dostęp do kontrolek sieci Web i ich odpowiednich właściwości, przekazywanie ich wartości do usługi BLL.
Podczas tworzenia interfejsu edycji, niezależnie od tego, czy składa się on tylko z kontrolki TextBoxes, czy kolekcji różnych kontrolek sieci Web, pamiętaj, aby poprawnie obsługiwać wartości bazy danych NULL
. Podczas ewidencjonowania wartości NULL
jest konieczne, aby nie tylko poprawnie wyświetlić istniejącą NULL
wartość w interfejsie edycji, ale także że oferujesz środki do oznaczania wartości jako NULL
. W przypadku elementów DropDownLists w elementach DataLists zazwyczaj oznacza to dodanie statycznej właściwości ListItem
, której Value
właściwość jest jawnie ustawiona na pusty ciąg (Value=""
) i dodanie do programu obsługi zdarzeń trochę kodu UpdateCommand
w celu określenia, czy NULL``ListItem
została wybrana.
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.
Specjalne podziękowania
Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Recenzenci w tym samouczku to Dennis Patterson, David Suru i Randy Schmidt. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.