Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor : Scott Mitchell
Te same funkcje TemplateFields dostępne w kontrolce GridView są również dostępne w kontrolce DetailsView. W tym samouczku wyświetlimy jeden produkt naraz przy użyciu kontrolki DetailsView zawierającej pola szablonu.
Wprowadzenie
Pole TemplateField zapewnia większą elastyczność renderowania danych niż pole BoundField, CheckBoxField, HyperLinkField i inne kontrolki pól danych. W poprzednim samouczku przyjrzeliśmy się używaniu PoleSzablonu w elemencie GridView do:
- Wyświetl wiele wartości pól danych w jednej kolumnie. W szczególności pola
FirstNameiLastNamezostały połączone w jedną kolumnę GridView. - Użyj alternatywnej kontrolki sieci Web, aby wyrazić wartość pola danych. Zobaczyliśmy, jak pokazać
HiredDatewartość przy użyciu kontrolki kalendarza. - Pokaż informacje o stanie na podstawie danych bazowych.
EmployeesChociaż tabela nie zawiera kolumny zwracającej liczbę dni pracy pracownika, mogliśmy wyświetlić takie informacje w przykładzie GridView w poprzednim samouczku przy użyciu metody TemplateField i formatowania.
Te same funkcje TemplateFields dostępne w kontrolce GridView są również dostępne w kontrolce DetailsView. W tym samouczku wyświetlimy jeden produkt naraz, używając kontrolki DetailsView zawierającej dwa TemplateFields. Pierwsze pole TemplateField połączy dane z pól UnitPrice, UnitsInStock i UnitsOnOrder w jeden wiersz DetailsView. Drugie pole TemplateField wyświetli wartość pola Discontinued, ale użyje metody formatowania, aby wyświetlić "TAK", jeśli Discontinued jest równe True, a "NIE" w przeciwnym razie.
Rysunek 1. Dwa pola szablonów są używane do dostosowywania wyświetlania (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Zaczynamy!
Krok 1. Powiązanie danych z kontrolką DetailsView
Jak wspomniano w poprzednim samouczku, podczas pracy z TemplateFields często najłatwiej jest rozpocząć od utworzenia kontrolki DetailsView zawierającej jedynie BoundFields, a następnie dodać nowe TemplateFields lub przekonwertować istniejące BoundFields na TemplateFields zgodnie z potrzebami. W związku z tym rozpocznij ten samouczek, dodając element DetailsView do strony za pośrednictwem projektanta i łącząc go z obiektem ObjectDataSource, który zwraca listę produktów. Te kroki spowodują utworzenie kontrolki DetailsView z polami BoundFields dla każdego pola wartości nie-Boolean produktu i pola CheckBoxField dla jednego pola wartości logicznej (wycofane).
Otwórz stronę DetailsViewTemplateField.aspx i przeciągnij element DetailsView z przybornika narzędzi do projektanta. Z inteligentnej etykiety kontrolki DetailsView wybierz opcję dodania nowej kontrolki ObjectDataSource, która wywołuje metodę klasy ProductsBLLGetProducts().
Rysunek 2. Dodawanie nowej kontrolki ObjectDataSource, która wywołuje metodę GetProducts() (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
W tym raporcie usuń pola ProductID, SupplierID, CategoryID i ReorderLevel BoundFields. Następnie zmień kolejność pól BoundField tak, aby CategoryName i SupplierName pojawiały się natychmiast po ProductName polu BoundField. Możesz dostosować HeaderText właściwości i właściwości formatowania dla obiektów BoundFields według własnych potrzeb. Podobnie jak w przypadku kontrolki GridView, te edycje na poziomie BoundField można wykonać za pomocą okna dialogowego Pól (dostępnego po kliknięciu linku Edytuj pola w inteligentnym tagu kontrolki SzczegółyWidoku) lub za pomocą składni deklaratywnej. Na koniec wyczyść wartości właściwości Height i Width kontrolki DetailsView, aby umożliwić jej rozwinięcie na podstawie wyświetlanych danych, i zaznacz pole wyboru "Włącz stronicowanie" w tagu inteligentnym.
Po wprowadzeniu tych zmian znaczniki deklaratywne kontrolki DetailsView powinny wyglądać podobnie do następujących:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="Units In Stock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="Units On Order" SortExpression="UnitsOnOrder" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
Poświęć chwilę, aby wyświetlić stronę za pomocą przeglądarki. Na tym etapie powinieneś zobaczyć listę zawierającą pojedynczy produkt (Chai) z wierszami pokazującymi nazwę produktu, kategorię, dostawcę, cenę, jednostki w magazynie, jednostki zamówione i stan wycofania.
Rysunek 3. Szczegóły produktu są wyświetlane przy użyciu serii pól powiązanych (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 2: Łączenie ceny, jednostek w magazynie oraz jednostek w zamówieniu w jednym wierszu
Element DetailsView zawiera wiersz dla pól UnitPrice, UnitsInStock i UnitsOnOrder. Możemy połączyć te pola danych w jeden wiersz z użyciem TemplateField, dodając nowe pole szablonu lub przekształcając jedno z istniejących pól UnitPrice, UnitsInStock i UnitsOnOrder BoundFields na pole szablonu. Chociaż osobiście preferuję konwertowanie istniejących pól BoundFields, przećwiczmy, dodając nowe pole szablonu.
Zacznij od kliknięcia linku Edytuj Pola w inteligentnym tagu DetailsView w celu wyświetlenia okna dialogowego Pola. Następnie dodaj nowe pole szablonu i ustaw jego HeaderText właściwość na wartość "Price and Inventory" i przenieś nowe pole szablonu, aby było umieszczone nad polem UnitPrice BoundField.
Rysunek 4. Dodawanie nowego pola szablonu do kontrolki DetailsView (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Ponieważ to nowe pole szablonu będzie zawierać wartości wyświetlane obecnie w polach UnitPrice, UnitsInStocki UnitsOnOrder BoundFields, usuńmy je.
Ostatnim zadaniem dla tego kroku jest zdefiniowanie ItemTemplate znaczników dla pola szablonu Price and Inventory, które można wykonać za pomocą interfejsu edycji szablonu kontrolki DetailsView w Projektancie lub ręcznie za pomocą składni deklaratywnej kontrolki. Podobnie jak w przypadku kontrolki GridView, interfejs edytowania szablonu kontrolki DetailsView można uzyskać, klikając link Edytuj szablony w tagu inteligentnym. W tym miejscu możesz wybrać szablon do edycji z listy rozwijanej, a następnie dodać wszystkie kontrolki sieci Web z przybornika.
Na potrzeby tego samouczka zacznij od dodania kontrolki Etykieta do pola szablonu ItemTemplatePrice and Inventory TemplateField. Kliknij link Edytuj elementy DataBindings z inteligentnej etykiety kontrolki etykiety sieci Web i powiąż właściwość Text z polem UnitPrice.
Rysunek 5. Powiązanie właściwości etykiety Text z polem UnitPrice danych (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Formatowanie ceny jako waluty
Po dodaniu kontrolka Etykieta internetowa Price and Inventory TemplateField będzie teraz wyświetlać tylko cenę wybranego produktu. Rysunek 6 przedstawia zrzut ekranu przedstawiający postęp do tej pory po wyświetleniu w przeglądarce.
Rysunek 6. Pole ceny i spisu Pokazuje cenę (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Należy pamiętać, że cena produktu nie jest sformatowana jako waluta. W przypadku pola boundfield formatowanie jest możliwe, ustawiając HtmlEncode właściwość na False i DataFormatString właściwość na {0:formatSpecifier}. Jednak w przypadku TemplateField wszelkie instrukcje formatowania muszą być określone w składni powiązania danych lub za pomocą metody formatowania zdefiniowanej gdzieś w kodzie aplikacji (na przykład w klasie code-behind strony ASP.NET).
Aby określić formatowanie składni powiązania danych używanej w kontrolce sieciowej Label, wróć do okna dialogowego DataBindings, klikając link Edytuj DataBindings z inteligentnej etykiety Label. Możesz wpisać instrukcje formatowania bezpośrednio na liście rozwijanej Format lub wybrać jeden ze zdefiniowanych ciągów formatu. Podobnie jak we właściwości BoundField DataFormatString formatowanie jest określane przy użyciu polecenia {0:formatSpecifier}.
UnitPrice W polu użyj formatowania waluty określonego przez wybranie odpowiedniej wartości listy rozwijanej lub wpisanie {0:C} ręcznie.
Rysunek 7. Formatowanie ceny jako waluty (kliknij, aby wyświetlić obraz pełnowymiarowy)
Deklaratywnie specyfikacja formatowania jest wskazywana jako drugi parametr do metody Bind lub Eval. Ustawienia wprowadzone właśnie za pośrednictwem projektanta powodują następujące wyrażenie powiązania danych w deklaratywnym kodzie:
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>
Dodawanie pozostałych pól danych do pola templateField
Na tym etapie wyświetliliśmy i sformatowaliśmy pole danych UnitPrice w polu szablonu ceny i zapasu, ale nadal musimy wyświetlić pola UnitsInStock i UnitsOnOrder. Wyświetlmy je w wierszu poniżej ceny i w nawiasach. Z interfejsu edytowania szablonu w Projektancie można dodać taki znacznik, umieszczając kursor w szablonie i po prostu wpisując tekst do wyświetlenia. Alternatywnie można wprowadzić ten znacznik bezpośrednio w składni deklaratywnej.
Dodaj statyczne znaczniki, kontrolki etykiet Web oraz składnię powiązania danych, aby pole szablonu ceny i zapasów wyświetlało informacje o cenie i zapasach w następujący sposób:
Cena jednostkowa
(W magazynie / na zamówienie:UnitsInStock / UnitsOnOrder)
Po wykonaniu tego zadania, znacznik deklaratywny kontrolki DetailsView powinien wyglądać jak przedstawiono poniżej:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="Product" SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:TemplateField HeaderText="Price and Inventory">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:Label>
<br />
<strong>
(In Stock / On Order: </strong>
<asp:Label ID="Label2" runat="server"
Text='<%# Eval("UnitsInStock") %>'></asp:Label>
<strong>/</strong>
<asp:Label ID="Label3" runat="server"
Text='<%# Eval("UnitsOnOrder") %>'>
</asp:Label><strong>)</strong>
</ItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
W wyniku tych zmian skonsolidowaliśmy informacje o cenach i zapasach w pojedynczy wiersz DetailsView.
Rysunek 8. Informacje o cenie i spisie są wyświetlane w jednym wierszu (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Krok 3. Dostosowywanie informacji o polu wycofanym
Kolumna ProductsDiscontinued tabeli jest wartością bitową wskazującą, czy produkt został przerwany. W przypadku powiązania kontrolki DetailsView (lub GridView) do kontrolki źródła danych, pola o wartościach logicznych, takie jak Discontinued, są implementowane jako CheckBoxFields, natomiast pola o wartościach innych niż logiczne, takie jak ProductID, ProductName, i tak dalej, są implementowane jako BoundFields. Pole CheckBoxField jest renderowane jako wyłączone pole wyboru, które jest zaznaczone, jeśli wartość pola danych przyjmuje wartość True, a w przeciwnym razie jest niezaznaczone.
Zamiast wyświetlać pole CheckBoxField, możemy zamiast tego wyświetlić tekst wskazujący, czy produkt nie został przerwany. Aby to osiągnąć, możemy usunąć pole CheckBoxField z kontrolki DetailsView, a następnie dodać pole BoundField, którego właściwość DataField została ustawiona na wartość Discontinued. Poświęć chwilę, aby to zrobić. Po tej zmianie w widoku DetailsView zostanie wyświetlony tekst "True" dla wycofanych produktów i "False" dla produktów, które są nadal aktywne.
Rysunek 9. Ciągi Prawda i Fałsz są używane do oznaczania stanu wycofania (kliknij, aby zobaczyć obraz w pełnym rozmiarze)
Załóżmy, że nie chcemy używać ciągów "True" ani "False", ale "YES" i "NO". Takie dostosowanie można wykonać przy użyciu pola szablonu i metody formatowania. Metoda formatowania może przyjmować dowolną liczbę parametrów wejściowych, ale musi zwrócić kod HTML (jako ciąg), aby wprowadzić go do szablonu.
Dodaj metodę formatowania do klasy code-behind strony DetailsViewTemplateField.aspx o nazwie DisplayDiscontinuedAsYESorNO, która jako parametr wejściowy przyjmuje obiekt Northwind.ProductsRow i zwraca ciąg. Zgodnie z opisem w poprzednim samouczku ta metoda musi być oznaczona jako Protected lub Public , aby była dostępna z szablonu.
Protected Function DisplayDiscontinuedAsYESorNO(discontinued As Boolean) As String
If discontinued Then
Return "YES"
Else
Return "NO"
End If
End Function
Ta metoda sprawdza parametr wejściowy (discontinued) i zwraca wartość "YES", jeśli jest Trueto , "NIE" w przeciwnym razie.
Uwaga
W metodzie formatowania omówionej w poprzednim samouczku przypominamy sobie, że przekazywaliśmy pole danych, które mogło zawierać wartości NULL i dlatego konieczne było sprawdzenie, czy wartość właściwości pracownika HiredDate odpowiadała wartości bazy danych NULL przed uzyskaniem dostępu do właściwości EmployeesRowHiredDate. Takie sprawdzenie nie jest tutaj potrzebne, ponieważ kolumna Discontinued nigdy nie może mieć przypisanych wartości bazy danych NULL . Ponadto dlatego metoda może akceptować parametr wejściowy typu logicznego zamiast akceptować wystąpienie ProductsRow lub parametr typu Object.
Po zakończeniu tej metody formatowania wystarczy wywołać ją z pola szablonu ItemTemplate. Aby utworzyć pole typu TemplateField, usuń Discontinued BoundField i dodaj nowe pole typu TemplateField lub przekonwertuj Discontinued BoundField na TemplateField. Następnie, z widoku znaczników deklaratywnych, zmodyfikuj pole TemplateField tak, aby zawierało tylko szablon ItemTemplate, który wywołuje metodę DisplayDiscontinuedAsYESorNO, przekazując wartość właściwości Discontinued bieżącego wystąpienia ProductRow. Dostęp do tego można uzyskać za pośrednictwem Eval metody . W szczególności znacznik TemplateField powinien wyglądać następująco:
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<%#DisplayDiscontinuedAsYESorNO(Convert.ToBoolean(Eval("Discontinued")))%>
</ItemTemplate>
</asp:TemplateField>
Spowoduje to wywołanie metody DisplayDiscontinuedAsYESorNO podczas renderowania elementu DetailsView, przekazując wartość Discontinued instancji ProductRow. Ponieważ metoda Eval zwraca wartość typu Object, ale metoda DisplayDiscontinuedAsYESorNO oczekuje parametru wejściowego typu Boolean, rzutujemy wartość zwracaną przez metodę Eval na Boolean. Następnie DisplayDiscontinuedAsYESorNO metoda zwróci wartość "YES" lub "NO" w zależności od odebranej wartości. Zwrócona wartość jest wyświetlana w tym wierszu DetailsView (zobacz Rysunek 10).
Rysunek 10. Wartości TAK lub NIE są teraz wyświetlane w wycofanym wierszu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Podsumowanie
Pole TemplateField w kontrolce DetailsView umożliwia większą elastyczność wyświetlania danych niż jest dostępna w innych kontrolkach pól i jest idealna w sytuacjach, w których:
- Wiele pól danych musi być wyświetlanych w jednej kolumnie GridView
- Dane najlepiej wyrażać przy użyciu kontrolki sieci Web, a nie zwykłego tekstu
- Dane wyjściowe zależą od danych bazowych, takich jak wyświetlanie metadanych lub ponowne formatowanie danych
Chociaż pola TemplateFields umożliwiają większą elastyczność w renderowaniu danych podstawowych kontrolki DetailsView, dane wyjściowe tej kontrolki nadal wyglądają nieco sztywno, ponieważ każde pole jest renderowane jako osobny wiersz w tabeli HTML <table>.
Kontrolka FormView zapewnia większą elastyczność konfigurowania renderowanych danych wyjściowych. Element FormView nie zawiera pól, ale tylko serię szablonów (ItemTemplate, EditItemTemplate, HeaderTemplateitd.). Zobaczymy, jak za pomocą kontrolki FormView uzyskać jeszcze większą kontrolę nad renderowanym układem w następnym samouczku.
Szczęśliwe programowanie!
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com.
Specjalne podziękowania
Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Główny recenzent tego samouczka był Dan Jagers. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.