第10回 Webフォームにおけるデータ連結 Part2 DataListコントロール:連載 プログラミングASP.NET ―ASP.NETによるWebアプリケーション実践開発講座― (3/4 ページ)
ASP.NETでは、データを一覧表示するのに、もはやTABLEタグやループ処理をチマチマ記述する必要はない。値の編集も一覧上で可能だ。
asp:DataListコントロールのテンプレート
前回の内容と合わせ、ここまででデータ連結に関する基本的な解説は終わりだ。ここからはasp:DataListコントロールの機能について解説を進めていくことにする。
すでに何度かリストで示したように、asp:DataListコントロールは次の書式で指定された<セルに表示する内容>部分を、反復値データ連結を使ってテーブルの各セルに展開する機能を備えている。<セルに表示する内容>には、データ連結式以外にも、サーバ・コントロールやHTMLエレメント、それにリテラル文字列を記述することが可能だ。ただし、ここに記述した内容はテーブルのTDエレメント、あるいはSPANエレメントで囲まれる形で出力されることには注意が必要である。<セルに表示する内容>にエレメントを記述するときは、必ず開始タグと終了タグを対にして、完結するように指定しなければならない。
<asp:DataList runat="server">
<ItemTemplate>
<セルに表示する内容>
</ItemTemplate>
</asp:DataList>
■テンプレートの種類
ところで、ここまでasp:DataListコントロールの要素としてItemTemplateだけを利用してきたが、そのほかにも次の表10.5に示すテンプレートが用意されている。これらのテンプレートをItemTemplateと併記することで、asp:DataListコントロールをカスタマイズすることができる。
ItemTemplate | データソースの各要素が連結される |
---|---|
AlternatingTemplate | このテンプレートが定義されていると、ItemTemplateと交互に連結されるようになる(1つの要素はItemTemplateとAlternatingTemplateの一方にのみ連結される) |
EditItemTemplate | 編集用テンプレート。EditItemIndexプロパティで指定された要素が連結される |
SelectedItemTemplate | 選択要素用テンプレート。SelectedIndexプロパティで指定された要素が連結される |
SeparatorTemplate | 各要素の合間に出力される(データソースへのデータ連結なし) |
HeaderTemplate | 上端に出力される(データソースへのデータ連結なし) |
FooterTemplate | 下端に出力される(データソースへのデータ連結なし) |
表10.5 asp:DataListコントロールのテンプレート |
データソースが連結されると、各要素はItemTemplate、AlternatingTemplate、EditItemTemplate、SelectedItemTemplateの4種類のテンプレートのいずれか1つによってデータ連結され、ページとして出力される。1つの要素が複数のテンプレートによってデータ連結されることはない。また、同じテンプレートを2回以上定義すると後で定義した方だけが有効になり、先に定義された方は無視される。
ItemTemplateテンプレートしか定義されていなかったときは、すべての要素がItemTemplateによってデータ連結されるが、それ以外の3つのテンプレートが定義されているときは、簡単なルールでデータ連結に使われるテンプレートが選択される。まず、ItemTemplateに加えて、AlternatingTemplateが定義されているときには、ItemTemplateとAlternatingTemplateが交互に参照されてデータ連結が行われるようになる。繰り返しになるが、1つの要素が複数のテンプレートによって連結されることはないので、1つの要素はItemTemplateとAlternatingTemplateの一方でのみ連結される。このテンプレートは主に、交互にセルの背景色を変えるなど、スタイルの設定用途に使われるものだ。この場合は、ItemTemplateと同じ<セルに表示する内容>をAlternatingTemplateにも指定して、AlternatingItemStyleとItemStyleを設定することになるが、Sytleについての解説はここでは割愛する。
残りの2つのテンプレートは、初期状態で使われることはないが、次のプロパティで指定された要素に対して、ItemTemplateやAlternatingTemplateよりも優先して使われる。EditItemTemplateはDataListクラスのEditItemIndexプロパティで指定された要素に対するデータ連結で使われ、SelectedItemTemplateは同じくSelectedIndexプロパティで指定された要素に対するデータ連結で使われる。これについて詳しくは後述する。
以上4つのテンプレートはデータソースに連結可能だが、残りのSeparatorTemplate、HeaderTemplate、FooterTemplateは連結できない(Container.DataItemオブジェクトを参照できない)。ただし、Pageクラスや、ページ内のクラスのプロパティやメソッドは参照できるので、単一値データ連結だけは利用可能だ。
■テンプレートの利用法
各テンプレートを利用したサンプル・プログラム(リスト10.4)を見ながら、テンプレートの具体的な利用方法について解説していこう。
<%@ PAGE LANGUAGE="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.IO" %>
<html>
<head>
<script runat="server">
void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
datalist1.DataSource = CreateDataSource();
datalist1.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 datalist1_Edit(object sender, DataListCommandEventArgs e) {
datalist1.EditItemIndex = e.Item.ItemIndex;
datalist1.DataSource = CreateDataSource();
datalist1.DataBind();
}
void datalist1_Update(object sender, DataListCommandEventArgs e) {
int fileid = (int) datalist1.DataKeys[e.Item.ItemIndex];
TextBox textbox = (TextBox) e.Item.FindControl("filename");
Message.Text = fileid.ToString() + " : " + textbox.Text;
datalist1.EditItemIndex = -1;
datalist1.DataSource = CreateDataSource();
datalist1.DataBind();
}
void datalist1_Cancel(object sender, DataListCommandEventArgs e) {
datalist1.EditItemIndex = -1;
datalist1.DataSource = CreateDataSource();
datalist1.DataBind();
}
void datalist1_Choice(object sender, DataListCommandEventArgs e) {
if (e.CommandName == "choice") {
datalist1.SelectedIndex = e.Item.ItemIndex;
datalist1.DataSource = CreateDataSource();
datalist1.DataBind();
}
}
</script>
</head>
<body>
<form runat="server">
<div align="center">
<asp:DataList id="datalist1"
CellPadding="4"
DataKeyField="fileid"
GridLines="Both"
RepeatColumns="2"
OnEditCommand="datalist1_Edit"
OnUpdateCommand="datalist1_Update"
OnCancelCommand="datalist1_Cancel"
OnItemCommand="datalist1_Choice"
runat="server">
<HeaderTemplate>
<p align="center"><%# Server.MapPath(".") %></p>
</HeaderTemplate>
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "filename") %>
( <%# DataBinder.Eval(Container.DataItem, "filesize") %> Bytes )
<asp:LinkButton Text="編集" CommandName="edit" runat="server" />
<asp:LinkButton Text="選択" CommandName="choice" runat="server" />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox id="filename" Text='<%# DataBinder.Eval(Container.DataItem, "filename") %>' runat="server" />
<asp:LinkButton Text="更新" CommandName="update" runat="server" />
<asp:LinkButton Text="キャンセル" CommandName="cancel" runat="server" />
</EditItemTemplate>
<SelectedItemTemplate>
<b>
<%# DataBinder.Eval(Container.DataItem, "filename") %>
( <%# DataBinder.Eval(Container.DataItem, "date") %> )
</b>
<asp:LinkButton Text="編集" CommandName="edit" runat="server" />
<asp:LinkButton Text="選択" CommandName="choice" runat="server" />
</SelectedItemTemplate>
<FooterTemplate>
<p align="right">
<%# (new DirectoryInfo(Server.MapPath("."))).GetFiles().Length %>個のファイルがあります
</p>
</FooterTemplate>
</asp:DataList>
<asp:Label id="Message" runat="server" />
</div>
</form>
</body>
</html>
sample09.aspxのダウンロード(sample09.zip)
リスト10.4では、カレント・ディレクトリ(sample09.aspxが格納されたディレクトリ)にあるファイルの一覧を取得して、これをデータソースとして利用している。そして、このデータソースをasp:DataListコントロールにデータ連結して、表としてページに出力する。出力された表のセルには、ファイル名とファイル・サイズ、それに[編集][選択]という2つのリンク・ボタンがそれぞれ出力される。これはItemTemplateが次のように指定されているためだ。
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "filename") %>
( <%# DataBinder.Eval(Container.DataItem, "filesize") %> Bytes )
<asp:LinkButton Text="編集" CommandName="edit" runat="server" />
<asp:LinkButton Text="選択" CommandName="choice" runat="server" />
</ItemTemplate>
ファイル名とファイル・サイズはデータ連結式によって出力され、リンク・ボタンはasp:LinkButtonを2つ並べて出力されている。なお、AlternatingItemTemplateは定義されていないため、すべての要素はItemTemplateでデータ連結される。
この[編集]ボタンをクリックすると、セルの内容がファイル名を含むテキスト・ボックスに置き換えられる。また、ボタンも[更新]と[キャンセル]に置き換えられる。これは、[編集]ボタンをクリックすると、次のEditItemTemplateで出力されるようになるためだ。
<EditItemTemplate>
<asp:TextBox id="filename"
Text='<%# DataBinder.Eval(Container.DataItem, "filename") %>'
runat="server" />
<asp:LinkButton Text="更新" CommandName="update" runat="server" />
<asp:LinkButton Text="キャンセル" CommandName="cancel" runat="server" />
</EditItemTemplate>
また[選択]ボタンをクリックすると、ファイル名がボールド表示されるようになる。これはSelectedItemTemplateが次のように定義されているためだ。
<SelectedItemTemplate>
<b>
<%# DataBinder.Eval(Container.DataItem, "filename") %>
( <%# DataBinder.Eval(Container.DataItem, "date") %> )
</b>
<asp:LinkButton Text="編集" CommandName="edit" runat="server" />
<asp:LinkButton Text="選択" CommandName="choice" runat="server" />
</SelectedItemTemplate>
最後にHeaderTemplateとFooterTemplateを以下に示す。前述したようにHeaderTemplateとFooterTemplateにデータソースは連結されないため、ここでは単一値連結だけを行い、ヘッダにはカレント・ディレクトリのパスを、フッタにはカレント・ディレクトリにあるファイル数を出力している。
<HeaderTemplate>
<p align="center"><%# Server.MapPath(".") %></p>
</HeaderTemplate>
<FooterTemplate>
<p align="right">
<%# (new DirectoryInfo(Server.MapPath("."))).GetFiles().Length %>個のファイルがあります
</p>
</FooterTemplate>
Copyright© Digital Advantage Corp. All Rights Reserved.