Udostępnij za pośrednictwem


Niestandardowe formatowanie na podstawie danych (C#)

Autor : Scott Mitchell

Pobierz plik PDF

Dostosowanie formatu kontrolki GridView, DetailsView lub FormView na podstawie powiązanych z nim danych można osiągnąć na wiele sposobów. W tym samouczku dowiesz się, jak wykonać formatowanie powiązane z danymi przy użyciu procedur obsługi zdarzeń DataBound i RowDataBound.

Wprowadzenie

Wygląd kontrolek GridView, DetailsView i FormView można dostosować za pomocą niezliczonych właściwości związanych z stylem. Właściwości takie jak CssClass, , Font, BorderWidthBorderStyleBorderColor, Width, i Height, między innymi, określają ogólny wygląd renderowanej kontrolki. Właściwości, w tym HeaderStyle, RowStyle, AlternatingRowStylei inne, umożliwiają stosowanie tych samych ustawień stylu do określonych sekcji. Podobnie te ustawienia stylu można stosować na poziomie pola.

Jednak w wielu scenariuszach wymagania dotyczące formatowania zależą od wartości wyświetlanych danych. Na przykład, aby zwrócić uwagę na produkty, które są niedostępne, raport z informacjami o produkcie może ustawić kolor tła na żółty dla tych produktów, których pola UnitsInStock i UnitsOnOrder są równocześnie równe 0. Aby podkreślić droższe produkty, możemy chcieć wyświetlić ceny tych produktów kosztujących ponad 75,00 USD w czcionki pogrubionej.

Dostosowanie formatu kontrolki GridView, DetailsView lub FormView na podstawie powiązanych z nim danych można osiągnąć na wiele sposobów. W tym samouczku przyjrzymy się temu, jak wykonać formatowanie powiązane z danymi przy użyciu programów obsługi zdarzeń DataBound i RowDataBound. W następnym samouczku zapoznamy się z alternatywnym podejściem.

Korzystanie z programu obsługi zdarzeń kontrolkiDataBoundDetailsView

Gdy dane są powiązane z kontrolką DetailsView, z kontrolki źródła danych lub przez programowe przypisywanie danych do właściwości kontrolki DataSource i wywoływanie jej DataBind() metody, następuje następująca sekwencja kroków:

  1. Zdarzenie kontrolki danych sieci Web DataBinding zostaje uruchomione.
  2. Dane są powiązane z kontrolką danych w sieci Web.
  3. Zdarzenie kontrolki danych sieci Web DataBound zostaje uruchomione.

Logika niestandardowa może być wstrzykiwana bezpośrednio po wykonaniu kroków 1 i 3 za pośrednictwem programu obsługi zdarzeń. Tworząc program obsługi zdarzeń dla DataBound zdarzenia, możemy programowo określić dane powiązane z kontrolką sieci Web danych i dostosować formatowanie zgodnie z potrzebami. Aby to zilustrować, utwórzmy element DetailsView, który wyświetli ogólne informacje o produkcie, ale wyświetli UnitPrice wartość pogrubioną kursywą, jeśli przekroczy 75,00 USD.

Krok 1. Wyświetlanie informacji o produkcie w widoku DetailsView

Otwórz stronę CustomColors.aspx w folderze CustomFormatting, przeciągnij kontrolkę DetailsView z przybornika do Projektanta, ustaw wartość jej właściwości ID na ExpensiveProductsPriceInBoldItalic, i powiąż ją z nową kontrolką ObjectDataSource, która wywołuje metodę ProductsBLL klasy GetProducts(). Szczegółowe kroki do wykonania tego celu zostały pominięte tutaj w celu zwięzłości, ponieważ szczegółowo zbadaliśmy je w poprzednich samouczkach.

Po powiązaniu obiektu ObjectDataSource z kontrolką DetailsView poświęć chwilę na zmodyfikowanie listy pól. Zdecydowałem się usunąć ProductID, SupplierID, CategoryID, UnitsInStock, UnitsOnOrder, ReorderLevel i Discontinued BoundFields oraz zmienić nazwę i ponownie sformatować pozostałe BoundFields. Wyczyściłem również ustawienia Width i Height. Ponieważ kontrolka DetailsView wyświetla tylko jeden rekord, musimy włączyć stronicowanie, aby umożliwić użytkownikowi końcowemu wyświetlanie wszystkich produktów. Aby to zrobić, zaznacz pole wyboru „Włącz stronicowanie” w inteligentnym tagu kontrolki DetailsView.

Zaznacz pole wyboru Włącz stronicowanie w inteligentnym tagu kontrolki DetailsView

Rysunek 1. Zaznacz pole wyboru Włącz stronicowanie w inteligentnym tagu kontrolki DetailsView (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Po tych zmianach znacznik DetailsView będzie następujący:

<asp:DetailsView ID="DetailsView1" runat="server" AllowPaging="True"
    AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" 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" DataFormatString="{0:c}"
          HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice" />
    </Fields>
</asp:DetailsView>

Pośmiń chwilę na przetestowanie tej strony w przeglądarce.

Kontrolka DetailsView wyświetla jeden produkt jednocześnie

Rysunek 2. Kontrolka DetailsView wyświetla jeden produkt jednocześnie (kliknij, aby wyświetlić obraz pełnowymiarowy)

Krok 2: Programatyczne ustalanie wartości danych w programie obsługi zdarzeń DataBound.

Aby wyświetlić cenę pogrubioną i kursywą dla tych produktów, których UnitPrice wartość przekracza 75,00 USD, musimy najpierw programowo ustalić wartość UnitPrice. W przypadku kontrolki DetailsView można zrobić to w programie obsługi zdarzeń DataBound. Aby utworzyć procedurę obsługi zdarzeń, kliknij element DetailsView w projektancie, a następnie przejdź do okna Właściwości. Naciśnij F4, aby go wyświetlić, jeśli nie jest widoczny, lub przejdź do menu Widok i wybierz opcję menu Okno właściwości. W oknie Właściwości kliknij ikonę błyskawicy, aby wyświetlić listę zdarzeń kontrolki DetailsView. Następnie dwukrotnie kliknij zdarzenie DataBound lub wpisz nazwę obsługiwacza zdarzeń, którą chcesz utworzyć.

Tworzenie programu obsługi zdarzeń dla zdarzenia DataBound

Rysunek 3. Tworzenie programu obsługi zdarzeń dla zdarzenia DataBound

Spowoduje to automatyczne utworzenie procedury obsługi zdarzeń i przejście do części kodu, w której została dodana. W tym momencie zobaczysz:

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{

}

Dostęp do danych powiązanych z kontrolką DetailsView można uzyskać za pośrednictwem DataItem właściwości . Pamiętaj, że wiążemy nasze kontrolki z silnie typowaną tabelą DataTable, która składa się z kolekcji silnie typowanych wystąpień DataRow. Gdy tabela DataTable jest powiązana z elementem DetailsView, pierwszy element DataRow w tabeli DataTable jest przypisywany do właściwości DetailsView DataItem . W szczególności właściwości DataItem jest przypisany obiekt DataRowView. Możemy użyć właściwości DataRowView elementu Row, aby uzyskać dostęp do bazowego obiektu DataRow, który jest w rzeczywistości instancją ProductsRow. Po utworzeniu tego ProductsRow wystąpienia możemy podjąć decyzję, po prostu sprawdzając wartości właściwości obiektu.

Poniższy kod ilustruje, jak określić, czy UnitPrice wartość powiązana z kontrolką DetailsView jest większa niż $75.00:

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)ExpensiveProductsPriceInBoldItalic.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice > 75m)
    {
        // TODO: Make the UnitPrice text bold and italic
    }
}

Uwaga / Notatka

Ponieważ UnitPrice może mieć NULL wartość w bazie danych, najpierw sprawdzamy, czy nie mamy do czynienia z wartością NULL, zanim uzyskamy dostęp do właściwości ProductsRowUnitPrice. Ta kontrola jest ważna, ponieważ jeśli próbujemy uzyskać dostęp do UnitPrice właściwości, gdy ma NULL ona wartość, ProductsRow obiekt zgłosi wyjątek StrongTypingException.

Krok 3. Formatowanie wartości UnitPrice w widoku Szczegółów

W tym momencie możemy określić, czy wartość UnitPrice powiązana z kontrolką DetailsView przekracza 75,00 USD, ale jeszcze nie zobaczyliśmy, jak za pomocą kodu dostosować formatowanie kontrolki DetailsView. Aby zmodyfikować formatowanie całego wiersza w widoku DetailsView, programowo uzyskaj dostęp do wiersza przy użyciu polecenia DetailsViewID.Rows[index]; aby zmodyfikować określoną komórkę, uzyskaj dostęp za pomocą polecenia DetailsViewID.Rows[index].Cells[index]. Po utworzeniu odwołania do wiersza lub komórki możemy dostosować jego wygląd, ustawiając jego właściwości powiązane ze stylem.

Uzyskiwanie dostępu do wiersza programowo wymaga znajomości indeksu wiersza, który zaczyna się od 0. Wiersz UnitPrice jest piątym wierszem w widoku DetailsView, co daje mu indeks 4, dzięki czemu jest programowo dostępny za pomocą elementu ExpensiveProductsPriceInBoldItalic.Rows[4]. W tym momencie zawartość całego wiersza może być wyświetlana pogrubioną czcionką kursywą przy użyciu następującego kodu:

ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Bold = true;
ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Italic = true;

Spowoduje to jednak, że zarówno etykieta (Cena), jak i wartość będą pogrubione i kursywą. Jeśli chcemy ustawić wartości pogrubione i kursywę, musimy zastosować to formatowanie do drugiej komórki w wierszu, co można osiągnąć przy użyciu następujących:

ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].Font.Bold = true;
ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].Font.Italic = true;

Ponieważ nasze samouczki do tej pory korzystały z arkuszy stylów, aby zachować czyste rozdzielenie renderowanych znaczników i informacji związanych ze stylem, zamiast ustawiać określone właściwości stylu, jak pokazano powyżej, użyjmy klasy CSS. Styles.css Otwórz arkusz stylów i dodaj nową klasę CSS o nazwie ExpensivePriceEmphasis z następującą definicją:

.ExpensivePriceEmphasis
{
    font-weight: bold;
    font-style: italic;
}

Następnie w obsłudze zdarzenia DataBound ustaw właściwość komórki CssClass na ExpensivePriceEmphasis. Poniższy kod przedstawia procedurę DataBound obsługi zdarzeń w całości:

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)ExpensiveProductsPriceInBoldItalic.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice > 75m)
    {
        ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].CssClass =
            "ExpensivePriceEmphasis";
    }
}

Podczas przeglądania Chai, który kosztuje mniej niż $75,00, cena jest wyświetlana w normalnej czcionce (patrz Rysunek 4). Jednak podczas wyświetlania Mishi Kobe Niku, który ma cenę 97,00 dolarów, cena jest wyświetlana pogrubioną i kursywną czcionką (patrz Rysunek 5).

Ceny mniejsze niż $75.00 są wyświetlane w normalnej czcionki

Rysunek 4. Ceny mniejsze niż 75,00 USD są wyświetlane w normalnej czcionki (kliknij, aby wyświetlić obraz pełnowymiarowy)

Ceny drogich produktów są wyświetlane w pogrubioną kursywą

Rysunek 5. Ceny drogich produktów są wyświetlane w czcionki pogrubionej kursywy (kliknij, aby wyświetlić obraz pełnowymiarowy)

Używanie programu obsługi zdarzeń kontrolkiDataBoundFormView

Kroki ustalania danych bazowych powiązanych z kontrolką FormView są identyczne z instrukcjami dla kontrolki DetailsView: utwórz DataBound procedurę obsługi zdarzeń, zrzuć właściwość DataItem na odpowiedni typ obiektu powiązany z kontrolką i zdecyduj, jak kontynuować. Kontrolki FormView i DetailsView różnią się jednak sposobem aktualizowania wyglądu interfejsu użytkownika.

Obiekt FormView nie zawiera żadnych pól BoundFields, więc brakuje mu zbioru Rows. Zamiast tego obiekt FormView składa się z szablonów, które mogą zawierać kombinację statycznego HTML, kontroli webowych i składni wiązania danych. Dostosowanie stylu kontrolki FormView zazwyczaj polega na zmianie wyglądu jednej lub kilku kontrolek sieciowych w szablonach FormView.

Aby to zilustrować, użyjmy widoku FormView do wyświetlenia listy produktów, podobnie jak w poprzednim przykładzie, ale tym razem wyświetlmy tylko nazwę produktu i jednostki w magazynie, przy czym jednostki w magazynie wyświetlane będą w czerwonej czcionce, jeśli ich liczba jest mniejsza lub równa 10.

Krok 4. Wyświetlanie informacji o produkcie w widoku FormView

Dodaj element FormView do strony poniżej elementu CustomColors.aspx DetailsView i ustaw jego właściwość ID na LowStockedProductsInRed. Powiąż element FormView z kontrolką ObjectDataSource utworzoną na podstawie poprzedniego kroku. Spowoduje to utworzenie obiektu ItemTemplate, EditItemTemplatei InsertItemTemplate dla kontrolki FormView. Usuń kontrolki EditItemTemplate i InsertItemTemplate i uprość element ItemTemplate, aby uwzględnić tylko wartości ProductName i UnitsInStock, każda w swojej odpowiednio nazwanej kontrolce etykiet. Podobnie jak w przypadku kontrolki DetailsView z wcześniejszego przykładu, zaznacz również pole wyboru Włącz stronicowanie w tagu inteligentnym kontrolki FormView.

Po wprowadzeniu tych zmian znaczniki widoku FormView powinny wyglądać podobnie do następujących:

<asp:FormView ID="LowStockedProductsInRed" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True"
    EnableViewState="False" runat="server">
    <ItemTemplate>
        <b>Product:</b>
        <asp:Label ID="ProductNameLabel" runat="server"
         Text='<%# Bind("ProductName") %>'>
        </asp:Label><br />
        <b>Units In Stock:</b>
        <asp:Label ID="UnitsInStockLabel" runat="server"
          Text='<%# Bind("UnitsInStock") %>'>
        </asp:Label>
    </ItemTemplate>
</asp:FormView>

Zwróć uwagę, że element ItemTemplate zawiera:

  • Statyczny kod HTML tekst "Product:" i "Units In Stock:" wraz z elementami <br /> i <b> .
  • Kontrolki webowe dwie kontrolki Label, ProductNameLabel i UnitsInStockLabel.
  • Składnia wiązania danych i <%# Bind("ProductName") %>, która przypisuje wartości z tych pól do właściwości kontrolek Etykiety <%# Bind("UnitsInStock") %>.

Krok 5: Programowe określanie wartości danych w programie obsługi zdarzeń związanych z danymi

Po zakończeniu oznaczenia FormView następnym krokiem jest programowe określenie, czy UnitsInStock jest mniejsza lub równa 10. Jest to realizowane w dokładnie taki sam sposób w widoku FormView, jak w DetailsView. Rozpocznij od utworzenia obsługiwacza dla zdarzenia DataBound w FormView.

Utwórz program obsługi zdarzenia DataBound

Rysunek 6. Tworzenie programu obsługi zdarzeń DataBound

W programie obsługi zdarzeń rzutuj właściwość DataItem FormView na wystąpienie ProductsRow i określ, czy wartość UnitsInPrice jest taka, że musimy wyświetlić ją w czerwonej czcionce.

protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)LowStockedProductsInRed.DataItem).Row;
    if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)
    {
        // TODO: Make the UnitsInStockLabel text red
    }
}

Krok 6. Formatowanie kontrolki UnitsInStockLabel Label w elemencie ItemTemplate elementu FormView

Ostatnim krokiem jest sformatowanie wyświetlanej UnitsInStock wartości czerwoną czcionką, jeśli wartość jest 10 lub mniejsza. Aby to osiągnąć, musimy programowo uzyskać dostęp do kontrolki UnitsInStockLabel w ItemTemplate i ustawić jej właściwości stylu, aby jego tekst był wyświetlany na czerwono. Aby uzyskać dostęp do kontrolki sieci Web w szablonie, użyj FindControl("controlID") metody w następujący sposób:

WebControlType someName = (WebControlType)FormViewID.FindControl("controlID");

W naszym przykładzie chcemy uzyskać dostęp do kontrolki Etykieta, której ID wartość to UnitsInStockLabel, więc użyjemy:

Label unitsInStock =
    (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel");

Po uzyskaniu programowego odwołania do kontrolki sieci Web możemy w razie potrzeby modyfikować jej właściwości związane ze stylem. Podobnie jak w poprzednim przykładzie, utworzyłem klasę CSS o nazwie Styles.css w LowUnitsInStockEmphasis. Aby zastosować ten styl do kontrolki etykiety Web, ustaw jej właściwość CssClass odpowiednio.

protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((DataRowView)LowStockedProductsInRed.DataItem).Row;
    if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)
    {
        Label unitsInStock =
            (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel");

        if (unitsInStock != null)
        {
          unitsInStock.CssClass = "LowUnitsInStockEmphasis";
        }
    }
}

Uwaga / Notatka

Składnia formatowania szablonu, używana do programowego uzyskiwania dostępu do kontrolki sieci Web przy użyciu FindControl("controlID"), a następnie do ustawiania jej właściwości związanych ze stylem, może być również stosowana podczas korzystania z pól TemplateFields w kontrolkach DetailsView lub GridView. Przeanalizujemy TemplateFields w naszym następnym samouczku.

Na rysunku 7 przedstawiono widok FormView podczas wyświetlania produktu, którego UnitsInStock wartość jest większa niż 10, podczas gdy produkt na rysunku 8 ma jego wartość mniejszą niż 10.

W przypadku produktów z wystarczająco dużymi jednostkami w magazynie nie zastosowano niestandardowego formatowania

Rysunek 7. W przypadku produktów z wystarczająco dużymi jednostkami w magazynie nie zastosowano niestandardowego formatowania (kliknij, aby wyświetlić obraz pełnowymiarowy)

Liczba jednostek w magazynie jest wyświetlana na czerwono dla tych produktów z wartościami 10 lub mniejszymi

Rysunek 8. Liczba jednostek w magazynie jest wyświetlana na czerwono dla tych produktów z wartościami 10 lub mniejszymi (kliknij, aby wyświetlić obraz pełnowymiarowy)

Formatowanie przy użyciu zdarzenia GridViewRowDataBound

Wcześniej przeanalizowaliśmy sekwencję kroków, które kontrolki DetailsView i FormView przechodzą przez proces łączenia danych. Przyjrzyjmy się tym krokom raz jeszcze, dla odświeżenia pamięci.

  1. Zdarzenie kontrolki danych sieci Web DataBinding zostaje uruchomione.
  2. Dane są powiązane z kontrolką danych w sieci Web.
  3. Zdarzenie kontrolki danych sieci Web DataBound zostaje uruchomione.

Te trzy proste kroki są wystarczające dla kontrolki DetailsView i FormView, ponieważ wyświetlają tylko jeden rekord. W przypadku kontrolki GridView, która wyświetla wszystkie powiązane z nią rekordy (nie tylko pierwszy), krok 2 jest nieco bardziej skomplikowany.

W kroku 2 funkcja GridView wylicza źródło danych, a dla każdego rekordu tworzy GridViewRow wystąpienie i wiąże z nim bieżący rekord. Dla każdego GridViewRow dodanego elementu GridView są wywoływane dwa zdarzenia:

  • RowCreateduruchamia się po utworzeniu GridViewRow
  • RowDataBound zostaje uruchomiony po powiązaniu bieżącego rekordu z GridViewRow.

W przypadku kontrolki GridView powiązanie danych jest dokładniej opisane przez następującą sekwencję kroków:

  1. Zdarzenie GridView jest DataBinding uruchamiane.

  2. Dane są powiązane z kontrolką GridView.

    Dla każdego rekordu w źródle danych

    1. Tworzenie GridViewRow obiektu
    2. Wyzwol zdarzenie RowCreated
    3. Powiąż rekord z GridViewRow
    4. Wyzwol zdarzenie RowDataBound
    5. Dodawanie elementu GridViewRow do kolekcji Rows
  3. Zdarzenie GridView jest DataBound uruchamiane.

Aby dostosować format poszczególnych rekordów kontrolki GridView, musimy utworzyć program obsługi zdarzeń dla RowDataBound zdarzenia. Aby to zilustrować, dodajmy element GridView do CustomColors.aspx strony zawierającej nazwę, kategorię i cenę każdego produktu, wyróżniając te produkty, których cena jest mniejsza niż 10,00 USD z żółtym kolorem tła.

Krok 7: Wyświetlanie informacji o produkcie w GridView

Dodaj element GridView pod elementem FormView z poprzedniego przykładu i ustaw jego właściwość ID na HighlightCheapProducts. Ponieważ mamy już obiekt ObjectDataSource, który zwraca wszystkie produkty na stronie, powiąż element GridView z tym elementem. Na koniec zmodyfikuj pola BoundFields kontrolki GridView, aby uwzględnić tylko nazwy, kategorie i ceny produktów. Po wykonaniu tych edycji znaczniki GridView powinny wyglądać następująco:

<asp:GridView ID="HighlightCheapProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
          SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category"
          ReadOnly="True" SortExpression="CategoryName" />
        <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
          HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>

Rysunek 9 przedstawia postęp do tego punktu po wyświetleniu za pośrednictwem przeglądarki.

Kontrolka GridView wyświetla listę nazw, kategorii i ceny dla każdego produktu

Rysunek 9. Kontrolka GridView wyświetla listę nazw, kategorii i cen dla każdego produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Krok 8. Programowe określanie wartości danych w programie obsługi zdarzeń RowDataBound

Gdy element ProductsDataTable jest powiązany z kontrolką GridView, jego wystąpienia ProductsRow są w pełni wyliczone, a dla każdego ProductsRow tworzony jest obiekt GridViewRow. Właściwość GridViewRowDataItem jest przypisywana do określonego obiektu ProductRow, po czym wywoływana jest procedura obsługi zdarzenia RowDataBound GridView. Aby określić UnitPrice wartość dla każdego produktu powiązanego z elementem GridView, musimy utworzyć procedurę obsługi zdarzeń dla zdarzenia GridView RowDataBound . W tej procedurze obsługi zdarzeń możemy sprawdzić wartość UnitPrice dla bieżącego GridViewRow i podjąć decyzję dotyczącą formatowania dla tego wiersza.

Tę procedurę obsługi zdarzeń można utworzyć przy użyciu tej samej serii kroków, co w przypadku elementów FormView i DetailsView.

Utworzenie programu obsługującego zdarzenie RowDataBound dla kontrolki GridView

Rysunek 10. Tworzenie programu obsługi zdarzeń dla zdarzenia GridView RowDataBound

Utworzenie procedury obsługi zdarzeń w ten sposób spowoduje automatyczne dodanie następującego kodu do części kodu strony ASP.NET:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{

}

Gdy zdarzenie RowDataBound zostanie wyzwolone, procedura obsługi zdarzenia otrzymuje jako drugi parametr obiekt typu GridViewRowEventArgs, który ma właściwość o nazwie Row. Ta właściwość zwraca odwołanie do GridViewRow, który właśnie został powiązany z danymi. Aby uzyskać dostęp do wystąpienia ProductsRow powiązanego z GridViewRow używamy właściwości DataItem w następujący sposób:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Get the ProductsRow object from the DataItem property...
    Northwind.ProductsRow product = (Northwind.ProductsRow)
        ((System.Data.DataRowView)e.Row.DataItem).Row;
    if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
    {
        // TODO: Highlight the row yellow...
    }
}

Podczas pracy z procedurą obsługi zdarzeń RowDataBound należy pamiętać, że element GridView składa się z różnych typów wierszy i że to zdarzenie jest uruchamiane dla wszystkich typów wierszy. GridViewRowTyp elementu może być określany przez jego RowType właściwość i może mieć jedną z możliwych wartości:

  • DataRow wiersz powiązany z rekordem z obiektu GridView DataSource
  • EmptyDataRowwiersz wyświetlany, jeśli kontrolka GridView jest pusta DataSource
  • Footer wiersz stopki; pokazywany, jeśli właściwość GridView jest ustawiona na ShowFooter
  • Header wiersz nagłówka; pokazano, czy właściwość ShowHeader kontrolki GridView jest ustawiona na true (wartość domyślna)
  • Pager w przypadku elementów GridView, które implementują stronicowanie, wiersz wyświetlający interfejs stronicowania
  • Separator nie jest używany dla kontrolki GridView, ale używany przez RowType właściwości webowych kontrolek danych DataList i Repeater, dwie kontrolki omówimy w przyszłych samouczkach

Ponieważ wiersze EmptyDataRow, Header, Footer, i Pager nie są skojarzone z rekordem DataSource, zawsze będą miały wartość null w jego właściwości DataItem. Z tego powodu przed podjęciem próby pracy z bieżącą GridViewRowDataItem właściwością musimy najpierw upewnić się, że mamy do czynienia z elementem DataRow. Można to zrobić, sprawdzając właściwość GridViewRowRowType w następujący sposób:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Make sure we are working with a DataRow
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Get the ProductsRow object from the DataItem property...
        Northwind.ProductsRow product = (Northwind.ProductsRow)
            ((System.Data.DataRowView)e.Row.DataItem).Row;
        if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
        {
          // TODO: Highlight row yellow...
        }
    }
}

Krok 9. Wyróżnienie żółtego wiersza, gdy wartość UnitPrice jest mniejsza niż 10,00 USD

Ostatnim krokiem jest programatyczne wyróżnienie całego GridViewRow, jeśli wartość UnitPrice tego wiersza jest mniejsza niż 10,00 $. Składnia uzyskiwania dostępu do wierszy lub komórek kontrolki GridView jest taka sama jak w przypadku kontrolki DetailsView: GridViewID.Rows[index] do uzyskania dostępu do całego wiersza, GridViewID.Rows[index].Cells[index] do uzyskania dostępu do określonej komórki. Jednak gdy program obsługi zdarzeń RowDataBound zostaje wywołany, powiązane dane GridViewRow nie zostały jeszcze dodane do kolekcji Rows w GridView. W związku z tym nie można uzyskać dostępu do bieżącego wystąpienia GridViewRow z programu obsługi zdarzeń RowDataBound przy użyciu kolekcji Wiersze.

Zamiast GridViewID.Rows[index], możemy odwołać się do bieżącego wystąpienia GridViewRow w obsłudze zdarzeń RowDataBound przy użyciu e.Row. To znaczy, że w celu wyróżnienia bieżącego wystąpienia GridViewRow z programu obsługi zdarzeń RowDataBound zastosujemy:

e.Row.BackColor = System.Drawing.Color.Yellow;

Zamiast ustawiać właściwość GridViewRow bezpośrednio, trzymajmy się korzystania z klas CSS. Utworzono klasę CSS o nazwie AffordablePriceEmphasis , która ustawia kolor tła na żółty. Ukończona RowDataBound procedura obsługi zdarzeń jest następująca:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
    // Make sure we are working with a DataRow
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // Get the ProductsRow object from the DataItem property...
        Northwind.ProductsRow product = (Northwind.ProductsRow)
            ((System.Data.DataRowView)e.Row.DataItem).Row;
        if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
        {
            e.Row.CssClass = "AffordablePriceEmphasis";
        }
    }
}

Najbardziej przystępne cenowo produkty są wyróżnione żółtym

Rysunek 11. Najbardziej przystępne cenowo produkty są wyróżnione kolorem żółtym (kliknij, aby wyświetlić obraz pełnowymiarowy)

Podsumowanie

W tym samouczku pokazano, jak sformatować kontrolkę GridView, DetailsView i FormView na podstawie danych powiązanych z kontrolką. W tym celu utworzyliśmy procedurę obsługi zdarzeń dla zdarzeń DataBound lub RowDataBound , gdzie dane bazowe zostały zbadane wraz ze zmianą formatowania, w razie potrzeby. Aby uzyskać dostęp do danych powiązanych z kontrolką DetailsView lub FormView, używamy DataItem właściwości w DataBound procedurze obsługi zdarzeń. Dla kontrolki GridView właściwość każdego GridViewRow wystąpienia DataItem zawiera dane powiązane z tym wierszem, które są dostępne w RowDataBound procedurze obsługi zdarzeń.

Składnia programowego dostosowywania formatowania kontrolki danych sieci Web zależy od kontrolki sieci Web i sposobu wyświetlania danych do sformatowania. W przypadku kontrolek DetailsView i GridView można uzyskać dostęp do wierszy i komórek według indeksu porządkowego. W przypadku elementu FormView, który używa szablonów, FindControl("controlID") metoda jest często używana do lokalizowania kontrolki sieci Web z poziomu szablonu.

W następnym samouczku przyjrzymy się, jak używać szablonów z GridView i DetailsView. Ponadto zobaczymy inną technikę dostosowywania formatowania na podstawie danych bazowych.

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 E.R. Gilmore, Dennis Patterson i Dan Jagers. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.