表形式でデータを表示可能なDataGridコントロールにさまざまなスタイルを適用し、より機能的でスタイリッシュなものにカスタマイズする。
前回では、ASP.NETの各コントロールに対して適用可能な「基本スタイル」や、テーブルを生成するコントロールに適用できる「テーブル・スタイル」について解説した。続編となる今回は、強力な表示能力を持つasp:DataGridコントロールに固有なスタイルから見ていく。
ItemStyleコントロールやAlternatingItemStyleコントロールに指定されたスタイルは、いずれもテーブル内の行に対して適用されたが、asp:DataGridコントロールでは、カラムに対して適用されるスタイルを設定することもできる。
aspDataGridコントロールを利用するには、asp:BoundColumnカラム・コントロールやasp:TemplateColumnカラム・コントロールを利用して、カラムに表示される情報を設定することはすでにDataGridコントロールの回で解説したとおりである。カラムに適用されるスタイルは、このカラム・コントロールの属性として設定する。
<asp:DataGrid runat="server">
<Columns>
<asp:BoundColumn ItemStyle-Width="10%">
……
</asp:BoundColumn>
<asp:TemplateColumn ItemStyle-HorizontalAlign="right">
……
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
各カラムには通常のアイテムだけでなく、ヘッダやフッタなども含まれることになるため、カラム・スタイルは常に、
<アイテム種>−<スタイル名>
の形式で指定される。<アイテム種>にはItemStyleやHeaderStyleなど、前回の表13-6に示したアイテム・スタイル・コントロールを、<スタイル名>にはWidthやHorizontalAlignなど、前回の表13-1と表13-5に示したテーブル・アイテム・スタイルを、それぞれ指定することができる。
■カラムのスタイルを動的に変更する
以上の書式でカラム・スタイルを指定できるが、行スタイルと同様にカラム・スタイルもプログラムから動的に設定することが可能だ。カラム・スタイルへアクセスするには、DataGridクラスのColumnsコレクション・プロパティを参照する。このコレクションには各カラムに対応するDataGridColumnオブジェクトが格納されており、DataGridColumn.ItemStyleプロパティやDataGridColumn.HeaderStyleプロパティを通してカラム・スタイルを設定することができる。
こうしてカラム・スタイルを設定するサンプルをリスト14-1に示す。リスト14-1ではテーブルのカラム・ヘッダがそれぞれリンク・ボタンになっていて、これをクリックするとそのカラムの色が変わる仕組みになっている。
<%@ PAGE LANGUAGE="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Drawing" %>
<html>
<head>
<script runat="server">
void Page_Load(object sender, EventArgs e) {
datagrid1.DataSource = CreateDataSource();
datagrid1.DataBind();
}
ICollection CreateDataSource() {
DirectoryInfo di = new DirectoryInfo(Server.MapPath("."));
FileInfo[] fi = di.GetFiles();
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("fileid", typeof(int)));
dt.Columns.Add(new DataColumn("filename", typeof(String)));
dt.Columns.Add(new DataColumn("filesize", typeof(long)));
dt.Columns.Add(new DataColumn("date", typeof(DateTime)));
for (int i = 0; i < fi.Length; i++) {
dr = dt.NewRow();
dr[0] = i;
dr[1] = fi[i].Name;
dr[2] = fi[i].Length;
dr[3] = fi[i].LastWriteTime;
dt.Rows.Add(dr);
}
DataView dv = new DataView(dt);
return dv;
}
void datagrid1_Select(object sender, DataGridCommandEventArgs e) {
DataGridColumn column
= datagrid1.Columns[Int32.Parse((string)e.CommandArgument)];
column.ItemStyle.ForeColor = Color.FromName("white");
column.ItemStyle.BackColor = Color.FromName("red");
/*
foreach (DataGridItem item in datagrid1.Items) {
if (item.ItemType == ListItemType.Item ||
item.ItemType == ListItemType.AlternatingItem) {
TableCell cell = (TableCell) item.Controls[column];
cell.ForeColor = Color.FromName("white");
cell.BackColor = Color.FromName("red");
}
}
*/
}
</script>
</head>
<body bgcolor="#333366">
<form runat="server">
<div align="center">
<asp:DataGrid id="datagrid1"
AutoGenerateColumns="false"
EnableViewState="false"
GridLines="None"
Width="100%"
CellSpacing="1"
BorderWidth="5"
BorderColor="#000080"
OnItemCommand="datagrid1_Select"
runat="server">
<HeaderStyle BackColor="cyan" ForeColor="white" />
<ItemStyle ForeColor="black" BackColor="#ffffcc" />
<AlternatingItemStyle
ForeColor="black" BackColor="#ffff66" />
<SelectedItemStyle
ForeColor="white" BackColor="#000080" />
<Columns>
<asp:TemplateColumn>
<HeaderTemplate>
<asp:LinkButton Text="ファイル名" CommandName="select"
CommandArgument="0" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<%# Server.HtmlEncode((string)DataBinder.Eval(
Container.DataItem, "filename")) %>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn ItemStyle-HorizontalAlign="right"
ItemStyle-Width="10%">
<HeaderTemplate>
<asp:LinkButton Text="サイズ" CommandName="select"
CommandArgument="1" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<%# (long)DataBinder.Eval(
Container.DataItem, "filesize") %>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn ItemStyle-Width="20%">
<HeaderTemplate>
<asp:LinkButton Text="更新日時" CommandName="select"
CommandArgument="2" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<%# DataBinder.Eval(
Container.DataItem, "date", "{0:d}") %>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
<asp:Label id="Message" runat="server" />
</div>
</form>
</body>
</html>
それでは、その仕組みを解説しよう。
まず、各ヘッダのリンク・ボタンは、以下のように設定されている。asp:DataGridコントロールのソート機能を利用するときには、AllowSorting属性を指定するだけでヘッダが自動的にリンク・ボタンとして機能したが、ソート以外の用途でヘッダをボタン化するには、こうして手作業でリンク・ボタンを配置しなければならない。従って、これは単なるコマンド・ボタンということになる。なお、ほかのカラムではCommandName属性には同じselectが、CommandArgument属性には左から順番に0、1、2、……が指定されている。このため、どのボタンをクリックしても同じイベント・ハンドラが呼び出されるが(OnItemCommand="datagrid1_Select"が指定されている)、どのカラムがクリックされたかはCommandArgumentの値で判断できるようになっている。
<HeaderTemplate>
<asp:LinkButton Text="ファイル名" CommandName="select"
CommandArgument="0" runat="server" />
</HeaderTemplate>
イベント・ハンドラの実装は比較的単純だ。CommandArgumentに設定されている値を調べて、対応するカラムのスタイルを設定しているだけである。ただし、e.CommandArgumentは文字列として渡されるので、これをInt32.Parseメソッドを使ってint型数値に変換してから、DataGrid.Columnsコレクションのインデックスに指定している。
void datagrid1_Select(object sender, DataGridCommandEventArgs e) {
DataGridColumn column
= datagrid1.Columns[Int32.Parse((string)e.CommandArgument)];
column.ItemStyle.ForeColor = Color.FromName("white");
column.ItemStyle.BackColor = Color.FromName("red");
}
Copyright© Digital Advantage Corp. All Rights Reserved.