GridView, ListView でデータを一覧表示する際、それにデータバインドされたデータソースに含まれる各行の特定の列のデータの値を調べ、その値に応じて当該行をハイライトする方法について書きます。
元は MSDN フォーラムのスレッド「ListViewでの一覧表示で、取得したデータに応じて背景色を変えたい」での話です。
そのスレッドで自分が回答したことなのですが、忘れかけていたので自分のブログに備忘録として書いておくことにしました。また、ついでに GridView での実装例も書いておきます。
このブログの別の記事「GridView, ListView に合計表示」のコードをベースにしていますので、そちらも見てください。
その記事では、Microsoft が提供するサンプルデータベース Northwind の Orders というテーブルのレコードのうち、[CustomerID] が ALFKI という顧客の注文の [OrderID], [OrderDate], [Freight] フィールド一覧を表示しています。
Orders テーブルには出荷日を示す [ShippedDate] というフィールドが含まれています。ここでは、[ShippedDate] を調べて、ある日付より後に出荷されたレコードの行の背景色をハイライトしてみます。なお、ListView / GridView には [ShippedDate] フィールドは表示しません。
ListView での例
以下の画像は 1998/1/1 より後に出荷された注文のレコードをハイライトしたものです。
紹介した MSDN フォーラムのスレッドで書いたとおりですが、上のように表示するための具体的な方法を以下に書きます。
-
SqlDataSource の SELECT クエリに [ShippedDate] を追加します。
-
ListView の ItemTemplate 内の tr 要素をサーバーコントロールに変更して id を付与します。具体的には runat="server" id="datarow" という 2 つの属性を追加します(id 名は任意)。
-
例えば、1998/1/1 より後に出荷されたレコードを黄色でハイライトする場合、[ShippedDate] が 1998/1/1 より後のアイテムの中から FindControl メソッドで上記 2 でサーバーコントロールにした tr 要素を探し、それに style 属性を追加します。コードは以下のようになります。
protected void ListView1_ItemDataBound(object sender,
ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem lvdi = (ListViewDataItem)e.Item;
DataRowView drv = (DataRowView)lvdi.DataItem;
total = total + (decimal)drv["Freight"];
// 以下が追加した部分
DateTime date = new DateTime(1998, 1, 1, 0, 0, 0);
if ((DateTime)drv["ShippedDate"] > date)
{
HtmlControl tr = (HtmlControl)lvdi.FindControl("datarow");
if (tr != null)
{
tr.Attributes.Add("style", "background-color:yellow;");
}
}
}
}
GridView での例
上の ListView の場合と同様に、1998/1/1 より後に出荷された注文のレコードをハイライトしたものです。
上のように表示するための具体的な方法は以下の通りです。
-
SqlDataSource の SELECT クエリに [ShippedDate] を追加します。(ListView の場合と同様)
-
ListView の場合とは異なり、GridView のコードには手を加える必要はありません。GridView の RowDataBound イベントで GridViewRow を取得し、それの CssClass プロパティにスタイルを設定できますので。
-
上の ListView の場合と同様に、1998/1/1 より後に出荷されたレコードを黄色でハイライトする場合、[ShippedDate] を調べて 1998/1/1 より後であれば、当該行の GridViewRow オブジェクトを取得し、その CssClass プロパティを設定します。コードは以下のようになります。
protected void GridView1_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView drv = (DataRowView)e.Row.DataItem;
total = total + (decimal)drv["Freight"];
// 以下が追加した部分
DateTime date = new DateTime(1998, 1, 1, 0, 0, 0);
if ((DateTime)drv["ShippedDate"] > date)
{
e.Row.CssClass = "style1";
}
// ここまで
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
e.Row.Cells[1].Text = "Freight Total";
e.Row.Cells[2].Text = String.Format("${0:N2}", total);
e.Row.Cells[1].ColumnSpan = 2;
e.Row.Cells.RemoveAt(0);
}
}
e.Row.CssClass = "style1"; のところの style1 は別途定義してソースに追加してください。インラインで <title> 要素の下に書くなら以下のようにします。
<style type="text/css">
.style1
{
background-color: yellow;
}
</style>