Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor : Scott Mitchell
W tym samouczku przejdziemy przez przykłady, jak formatować wygląd kontrolek DataList i Repeater, używając funkcji formatowania w szablonach lub obsługując zdarzenie DataBound.
Wprowadzenie
Jak pokazano w poprzednim samouczku, lista DataList oferuje wiele właściwości związanych ze stylem, które wpływają na jej wygląd. W szczególności zobaczyliśmy, jak przypisać domyślne klasy CSS do właściwości DataList s HeaderStyle, ItemStyleAlternatingItemStyle, i SelectedItemStyle . Oprócz tych czterech właściwości, lista DataList zawiera wiele innych właściwości związanych ze stylem, takich jak Font, ForeColor, BackColor i BorderWidth, żeby wymienić tylko kilka. Kontrolka Repeater nie zawiera żadnych właściwości związanych ze stylem. Wszystkie takie ustawienia stylu należy wprowadzić bezpośrednio w znacznikach w szablonach Repeatera.
Często jednak sposób formatowania danych zależy od samych danych. Na przykład podczas listowania produktów możemy chcieć wyświetlić informacje o produkcie w jasnoszarym kolorze czcionki, jeśli zostanie wycofany z oferty, lub możemy zaznaczyć wartość UnitsInStock, jeśli wynosi zero. Jak pokazano w poprzednich samouczkach, kontrolki GridView, DetailsView i FormView oferują dwa różne sposoby formatowania ich wyglądu na podstawie danych:
-
Zdarzenie
DataBoundtworzy obsługę zdarzeń dla odpowiedniegoDataBoundzdarzenia, które jest uruchamiane po powiązaniu danych z każdym elementem (dla kontrolki GridView było to zdarzenieRowDataBound; dla elementu DataList i Repeater jest to zdarzenieItemDataBound). W tym programie obsługi zdarzeń można zbadać dane, które właśnie zostały powiązane, i podjąć decyzje dotyczące formatowania. Zbadaliśmy tę technikę w samouczku Custom Formatting Based Upon Data (Formatowanie niestandardowe na podstawie danych ). - Formatowanie funkcji w szablonach podczas używania TemplateFields w kontrolkach DetailsView lub GridView albo szablonu w kontrolce FormView możemy dodać funkcję formatowania do klasy code-behind strony ASP.NET, warstwy logiki biznesowej lub dowolnej innej biblioteki klas dostępnej z poziomu aplikacji internetowej. Ta funkcja formatowania może akceptować dowolną liczbę parametrów wejściowych, ale musi zwrócić kod HTML do renderowania w szablonie. Funkcje formatowania po raz pierwszy zostały zbadane w samouczku „Using TemplateFields w kontrolce GridView”.
Obie te techniki formatowania są dostępne za pomocą kontrolek DataList i Repeater. W tym samouczku omówimy przykłady przy użyciu obu technik dla obu kontrolek.
Korzystanie z programu obsługi zdarzeńItemDataBound
Gdy dane są powiązane z elementem DataList, z kontrolki źródła danych lub przez programowe przypisywanie danych do właściwości kontrolki DataSource i wywoływanie jej metody DataBind(), zdarzenie DataBinding elementu DataList jest aktywowane, źródło danych jest wyliczone, a każdy rekord danych jest powiązany z listą DataList. Dla każdego rekordu w źródle danych lista DataList tworzy DataListItem obiekt, który jest następnie powiązany z bieżącym rekordem. Podczas tego procesu DataList zgłasza dwa zdarzenia:
-
ItemCreateduruchamia się po utworzeniuDataListItem -
ItemDataBounduruchamia się po powiązaniu bieżącego rekordu zDataListItem
W poniższych krokach opisano proces wiązania danych dla kontrolki DataList.
Zdarzenie
DataBindingDataList jest uruchamianeDane są powiązane z DataList
Dla każdego rekordu w źródle danych
- Tworzenie
DataListItemobiektu - Uruchom zdarzenie
ItemCreated - Powiąż rekord z
DataListItem - Uruchom zdarzenie
ItemDataBound - Dodawanie elementu
DataListItemdo kolekcjiItems
- Tworzenie
Podczas wiązania danych z kontrolką Repeater, przechodzi przez dokładnie tę samą sekwencję kroków. Jedyną różnicą jest to, że zamiast tworzonych wystąpień DataListItem, Repeater używa RepeaterItemów.
Uwaga / Notatka
Czytelnik może zauważyć niewielką anomalię między sekwencją kroków, które występują, gdy element DataList i Repeater są powiązane z danymi, a gdy element GridView jest powiązany z danymi. Na końcu procesu powiązania danych kontrolka GridView zgłasza DataBound zdarzenie, jednak ani kontrolki DataList, ani Repeater nie mają takiego zdarzenia. Wynika to z faktu, że kontrolki DataList i Repeater zostały utworzone w czasach ASP.NET 1.x, zanim wzorzec obsługi zdarzeń przed- i po-poziomie stał się powszechny.
Podobnie jak w przypadku kontrolki GridView, jedną z opcji formatowania na podstawie danych jest utworzenie procedury obsługi dla zdarzenia ItemDataBound. Ta procedura obsługi zdarzeń sprawdzi dane, które dopiero co zostały powiązane z DataListItem lub RepeaterItem i zmieni formatowanie kontrolki zgodnie z potrzebami.
W przypadku kontrolki DataList można zaimplementować zmiany formatowania dla całego elementu przy użyciu właściwości związanych ze stylem DataListItem, które obejmują standardowe Font, ForeColor, BackColor, CssClass i tak dalej. Aby wpłynąć na formatowanie określonych kontrolek sieci Web w szablonie DataList, musimy programowo uzyskać dostęp i zmodyfikować styl tych kontrolek sieci Web. Zobaczyliśmy, jak to zrobić w samouczku Formatowanie niestandardowe oparte na danych. Podobnie jak kontrolka RepeaterItem Repeater, klasa nie ma właściwości związanych ze stylem, dlatego wszystkie zmiany związane ze stylem w RepeaterItem, wprowadzone w programie obsługi zdarzeń ItemDataBound, muszą być wykonywane poprzez programowe uzyskiwanie dostępu do kontrolek sieci Web w szablonie i ich aktualizację.
ItemDataBound Ponieważ technika formatowania elementów DataList i Repeater jest praktycznie identyczna, w naszym przykładzie skoncentrujemy się na korzystaniu z elementu DataList.
Krok 1. Wyświetlanie informacji o produkcie na liście danych
Zanim zaczniemy martwić się o formatowanie, najpierw utwórzmy stronę, która używa elementu DataList do wyświetlania informacji o produkcie. W poprzednim samouczku utworzyliśmy element DataList, który wyświetla nazwę produktu, kategorię, dostawcę, ilość na jednostkę i cenę. Powtórzmy tę funkcjonalność w tym samouczku. W tym celu możesz utworzyć ponownie obiekt DataList i jego obiekt ObjectDataSource od podstaw lub skopiować te kontrolki ze strony utworzonej w poprzednim samouczku () i wkleić je do strony na potrzeby tego samouczka (Basics.aspxFormatting.aspx).
pl-PL: Gdy już zreplikujesz funkcje DataList i ObjectDataSource z Basics.aspx do Formatting.aspx, poświęć chwilę na zmianę właściwości DataList ID z DataList1 na bardziej opisowe ItemDataBoundFormattingExample. Następnie wyświetl element DataList w przeglądarce. Jak pokazano na rysunku 1, jedyną różnicą formatowania między poszczególnymi produktami jest to, że kolor tła jest alternatywny.
Rysunek 1. Produkty są wyświetlane w kontrolce DataList (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
W tym samouczku sformatujmy DataList tak, aby wszystkie produkty z ceną mniejszą niż 20,00 USD miały zarówno nazwę, jak i cenę jednostkową wyróżnione na żółto.
Krok 2. Programowe określanie wartości danych w programie obsługi zdarzeń ItemDataBound
Ponieważ tylko te produkty z ceną poniżej 20,00 USD będą miały zastosowane niestandardowe formatowanie, musimy mieć możliwość określenia ceny poszczególnych produktów. Podczas powiązywania danych z Listą Danych, DataList wylicza rekordy w źródle danych i dla każdego rekordu tworzy instancję DataListItem, powiązując rekord źródła z DataListItem. Po powiązaniu danych określonego rekordu z bieżącym DataListItem obiektem zdarzenie DataList ItemDataBound zostanie wyzwolone. Możemy utworzyć procedurę obsługi zdarzeń dla tego zdarzenia, aby sprawdzić wartości danych dla bieżącej wartości DataListItem i, na podstawie tych wartości, wprowadzić wszelkie niezbędne zmiany formatowania.
ItemDataBound Utwórz zdarzenie dla elementu DataList i dodaj następujący kod:
protected void ItemDataBoundFormattingExample_ItemDataBound
(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
// Programmatically reference the ProductsRow instance bound
// to this DataListItem
Northwind.ProductsRow product =
(Northwind.ProductsRow)((System.Data.DataRowView)e.Item.DataItem).Row;
// See if the UnitPrice is not NULL and less than $20.00
if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
{
// TODO: Highlight the product's name and price
}
}
}
Chociaż koncepcja i semantyka programu obsługi zdarzeń DataList ItemDataBound są takie same jak te, które są używane przez program obsługi zdarzeń GridView RowDataBound w samouczku Niestandardowe formatowanie na podstawie danych , składnia różni się nieco.
ItemDataBound Gdy zdarzenie zostanie wyzwolone, DataListItem właśnie powiązane z danymi zostanie przekazane do odpowiedniego programu obsługi zdarzeń za pośrednictwem e.Item (zamiast e.Row, podobnie jak w przypadku programu obsługi zdarzeń GridView RowDataBound). Procedura obsługi zdarzeń DataList jest ItemDataBound uruchamiana dla każdego wiersza dodanego do DataList, w tym wierszy nagłówka, wierszy stopki i wierszy separatora. Informacje o produkcie są jednak powiązane tylko z wierszami danych. W związku z tym w przypadku używania ItemDataBound zdarzenia do inspekcji danych powiązanych z elementem DataList musimy najpierw upewnić się, że pracujemy z elementem danych. Można to zrobić, sprawdzając DataListItem właściwość sItemType, która może mieć jedną z następujących ośmiu wartości:
AlternatingItemEditItemFooterHeaderItemPagerSelectedItemSeparator
Item i AlternatingItem``DataListItem tworzą elementy danych DataList. Zakładając, że pracujemy z Item lub AlternatingItem, uzyskujemy dostęp do rzeczywistego wystąpienia ProductsRow, które zostało powiązane z bieżącym DataListItem. Właściwość DataListItem s DataItem zawiera odwołanie do DataRowView obiektu, którego Row właściwość zawiera odwołanie do rzeczywistego ProductsRow obiektu.
Następnie sprawdzamy ProductsRow właściwość wystąpienia UnitPrice . Ponieważ pole tabeli UnitPrice Products zezwala na NULL wartości, przed próbą uzyskania dostępu do właściwości UnitPrice należy najpierw sprawdzić, czy ma wartość NULL, używając metody IsUnitPriceNull(). Jeśli wartość UnitPrice nie jest równa NULL, sprawdźmy, czy jest mniejsza niż 20,00 USD. Jeśli rzeczywiście jest poniżej 20,00 dolarów, musimy zastosować własne formatowanie.
Krok 3. Wyróżnianie nazwy i ceny produktu
Gdy wiemy, że cena produktu jest mniejsza niż $20.00, wszystko, co pozostaje, to podkreślić jego nazwę i cenę. Aby to osiągnąć, musimy najpierw programowo odwołać się do kontrolek Label w ItemTemplate które wyświetlają nazwę i cenę produktu. Następnie musimy wyświetlić żółte tło. Te informacje o formatowaniu można stosować bezpośrednio, modyfikując właściwości Etykiety BackColor (LabelID.BackColor = Color.Yellow). W idealnym przypadku wszystkie kwestie związane z wyświetlaniem powinny być wyrażane za pomocą kaskadowych arkuszy stylów. W rzeczywistości mamy już arkusz stylów, który udostępnia żądane formatowanie zdefiniowane w Styles.css - AffordablePriceEmphasis, który został utworzony i omówiony w samouczku Formatowanie niestandardowe na podstawie danych.
Aby zastosować formatowanie, wystarczy ustawić dwie właściwości kontrolek CssClass etykiet sieci Web na AffordablePriceEmphasis, jak pokazano w poniższym kodzie:
// Highlight the product name and unit price Labels
// First, get a reference to the two Label Web controls
Label ProductNameLabel = (Label)e.Item.FindControl("ProductNameLabel");
Label UnitPriceLabel = (Label)e.Item.FindControl("UnitPriceLabel");
// Next, set their CssClass properties
if (ProductNameLabel != null)
ProductNameLabel.CssClass = "AffordablePriceEmphasis";
if (UnitPriceLabel != null)
UnitPriceLabel.CssClass = "AffordablePriceEmphasis";
Po ukończeniu obsługi zdarzenia ItemDataBound ponownie otwórz stronę Formatting.aspx w przeglądarce. Jak pokazano na rysunku 2, produkty o cenie poniżej 20,00 USD mają wyróżnioną zarówno nazwę, jak i cenę.
Rysunek 2. Wyróżniono te produkty mniejsze niż 20,00 USD (kliknij, aby wyświetlić obraz pełnowymiarowy)
Uwaga / Notatka
Ponieważ element DataList jest renderowany jako html <table>, jego DataListItem wystąpienia mają właściwości związane ze stylem, które można ustawić, aby zastosować określony styl do całego elementu. Jeśli na przykład chcemy wyróżnić cały element żółty, gdy jego cena była mniejsza niż 20,00 USD, możemy zastąpić kod, który odwołuje się do etykiet i ustawić ich CssClass właściwości następującym wierszem kodu: e.Item.CssClass = "AffordablePriceEmphasis" (zobacz Rysunek 3).
Kontrolki RepeaterItem, które tworzą kontrolkę Repeater, nie oferują jednak takich właściwości dotyczących stylu. W związku z tym zastosowanie formatowania niestandardowego do repeatera wymaga zastosowania właściwości stylu do kontrolek sieci Web w szablonach repeatera, podobnie jak na rysunku 2.
Rysunek 3. Cały element produktu jest wyróżniony dla produktów poniżej 20,00 USD (kliknij, aby wyświetlić obraz pełnowymiarowy)
Używanie funkcji formatowania z szablonu
W samouczku "Używanie pól szablonów w kontrolce GridView" (Using TemplateFields in the GridView Control) pokazano, jak używać funkcji formatowania w polu GridView TemplateField do zastosowania niestandardowego formatowania na podstawie danych powiązanych z wierszami kontrolki GridView. Funkcja formatowania to metoda, którą można wywołać z szablonu i zwraca kod HTML, który ma być emitowany w jego miejscu. Funkcje formatowania mogą znajdować się w klasie kodu za stroną ASP.NET lub mogą być scentralizowane w plikach klas w folderze App_Code lub w osobnym projekcie biblioteki klas. Przeniesienie funkcji formatowania z klasy związanej z kodem ASP.NET jest idealne, jeśli planujesz używać tej samej funkcji formatowania na wielu stronach ASP.NET lub w innych aplikacjach sieciowych ASP.NET.
Aby zademonstrować funkcje formatowania, informacje o produkcie powinny zawierać tekst [DISCONTINUED] obok nazwy produktu, jeśli jest wycofany. Ponadto pokażmy cenę w kolorze żółtym, jeśli jest mniejsza niż 20,00 USD (tak jak w przykładzie ItemDataBound procedury obsługi zdarzeń); jeśli cena wynosi 20,00 USD lub więcej, nie wyświetlajmy rzeczywistej ceny, ale wyświetlmy tekst "Proszę zadzwonić po wycenę". Rysunek 4 przedstawia zrzut ekranu przedstawiający listę produktów z zastosowanymi regułami formatowania.
Rysunek 4. W przypadku drogich produktów cena jest zastępowana tekstem, wywołaj ofertę cenową (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 1. Tworzenie funkcji formatowania
W tym przykładzie potrzebujemy dwóch funkcji formatowania: jednej, która wyświetla nazwę produktu wraz z tekstem [WYCOFANY ZE SPRZEDAŻY], w razie potrzeby, oraz drugiej, która wyświetla wyróżnioną cenę, jeśli jest mniejsza niż 20,00 USD, lub tekst "Proszę zadzwonić, aby uzyskać wycenę", w przeciwnym razie. Utwórzmy te funkcje w klasie ASP.NET w kodzie-behind strony i nazwijmy je DisplayProductNameAndDiscontinuedStatus oraz DisplayPrice. Oba sposoby muszą zwrócić kod HTML do renderowania jako ciąg, a oba muszą być oznaczone Protected (lub Public), aby można je było wywołać z deklaratywnej części składni strony ASP.NET. Kod dla tych dwóch metod jest następujący:
protected string DisplayProductNameAndDiscontinuedStatus
(string productName, bool discontinued)
{
// Return just the productName if discontinued is false
if (!discontinued)
return productName;
else
// otherwise, return the productName appended with the text "[DISCONTINUED]"
return string.Concat(productName, " [DISCONTINUED]");
}
protected string DisplayPrice(Northwind.ProductsRow product)
{
// If price is less than $20.00, return the price, highlighted
if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
return string.Concat("<span class=\"AffordablePriceEmphasis\">",
product.UnitPrice.ToString("C"), "</span>");
else
// Otherwise return the text, "Please call for a price quote"
return "<span>Please call for a price quote</span>";
}
Należy pamiętać, że DisplayProductNameAndDiscontinuedStatus metoda akceptuje wartości productName pól danych i discontinued jako wartości skalarne, natomiast DisplayPrice metoda akceptuje ProductsRow wystąpienie (zamiast wartości skalarnej unitPrice ). Oba podejścia będą skuteczne; jednak jeśli funkcja formatowania pracuje z wartościami skalarnymi, które mogą zawierać wartości z bazy danych NULL (na przykład UnitPrice; ani ProductName ani Discontinued nie pozwalają na wartości NULL), należy zachować szczególną ostrożność przy obsłudze tych danych wejściowych skalarnych.
W szczególności parametr wejściowy musi być typu Object , ponieważ wartość przychodząca może być wystąpieniem DBNull zamiast oczekiwanego typu danych. Ponadto należy sprawdzić, czy wartość przychodząca jest wartością bazy danych NULL . Oznacza to, że jeśli chcemy DisplayPrice , aby metoda akceptowała cenę jako wartość skalarną, musielibyśmy użyć następującego kodu:
protected string DisplayPrice(object unitPrice)
{
// If price is less than $20.00, return the price, highlighted
if (!Convert.IsDBNull(unitPrice) && ((decimal) unitPrice) < 20)
return string.Concat("<span class=\"AffordablePriceEmphasis\">",
((decimal) unitPrice).ToString("C"), "</span>");
else
// Otherwise return the text, "Please call for a price quote"
return "<span>Please call for a price quote</span>";
}
Należy pamiętać, że parametr wejściowy unitPrice jest typu Object oraz że instrukcja warunkowa została zmodyfikowana, aby sprawdzić, czy unitPrice jest DBNull lub nie. Ponadto, ponieważ unitPrice parametr wejściowy jest przekazywany jako Object, musi być rzutowany na wartość dziesiętną.
Krok 2: Wywoływanie funkcji formatowania z ItemTemplate w DataList
Dzięki funkcjom formatowania dodanym do plików zaplecza kodu naszej strony ASP.NET, pozostaje tylko wywołać te funkcje formatowania z elementu DataList ItemTemplate. Aby wywołać funkcję formatowania z szablonu, umieść wywołanie funkcji w składni powiązania danych:
<%# MethodName(inputParameter1, inputParameter2, ...) %>
W kontrolce sieciowej Label na liście danych ItemTemplateProductNameLabel obecnie wyświetlana jest nazwa produktu poprzez przypisanie jej właściwości Text wyniku <%# Eval("ProductName") %>. Aby wyświetlić nazwę wraz z tekstem [wycofane z użycia], w razie potrzeby zaktualizuj składnię deklaratywną, aby przypisać właściwości Text wartość metody DisplayProductNameAndDiscontinuedStatus. W tym celu musimy przekazać nazwę produktu i wartości dotyczące wycofania przy użyciu składni Eval("columnName").
Eval Zwraca wartość typu Object, ale DisplayProductNameAndDiscontinuedStatus metoda oczekuje parametrów wejściowych typu String i Boolean; dlatego musimy rzutować wartości zwracane przez Eval metodę do oczekiwanych typów parametrów wejściowych, w następujący sposób:
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# DisplayProductNameAndDiscontinuedStatus((string) Eval("ProductName"),
(bool) Eval("Discontinued")) %>'>
</asp:Label>
</h4>
Aby wyświetlić cenę, możemy po prostu ustawić właściwość UnitPriceLabel Label Text na wartość zwróconą przez metodę DisplayPrice, podobnie jak zrobiliśmy to dla wyświetlania nazwy produktu i tekstu [DISCONTINUED]. Jednak zamiast przekazywać jako UnitPrice parametr wejściowy skalarny, zamiast tego przekazujemy całe ProductsRow wystąpienie:
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# DisplayPrice((Northwind.ProductsRow)
((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>
Po wywołaniu funkcji formatowania, poświęć chwilę, aby obejrzeć postęp w przeglądarce. Ekran powinien wyglądać podobnie do rysunku 5, a wycofane produkty, w tym oznaczenie [WYCOFANY], oraz produkty, których cena przekracza 20,00 USD, mają zastąpioną cenę przez tekst Proszę o kontakt w celu uzyskania oferty cenowej.
Rysunek 5. W przypadku drogich produktów cena jest zastępowana tekstem, wywołaj ofertę cenową (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Podsumowanie
Formatowanie zawartości kontrolki DataList lub Repeater na podstawie danych można wykonać przy użyciu dwóch technik. Pierwszą techniką jest utworzenie obsługi zdarzenia dla ItemDataBound; uruchamia się ona, gdy każdy rekord w źródle danych jest powiązany z nowym DataListItem lub RepeaterItem. W procedurze ItemDataBound obsługi zdarzeń można zbadać bieżące dane elementu, a następnie można zastosować formatowanie do zawartości szablonu lub , dla DataListItem s, do całego elementu.
Alternatywnie można zrealizować niestandardowe formatowanie za pomocą funkcji formatowania. Funkcja formatowania to metoda, która może być wywoływana z szablonów DataList lub Repeater i zwraca kod HTML do wyświetlenia w zamian. Często kod HTML zwracany przez funkcję formatowania jest określany przez wartości powiązane z bieżącym elementem. Te wartości można dostarczać do funkcji formatowania jako wartości skalarne lub przekazując cały obiekt powiązany z elementem (np. ProductsRow wystąpienie).
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łówni recenzenci tego samouczka to Yaakov Ellis, Randy Schmidt i Liz Shulok. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.