DataGridに動的にテンプレートカラムを作成するにあたってに
投稿するための実験。
お題目は、DataGrid に動的にテンプレート列を追加したときに、テンプレート列内のコントロールにデータ項目をバインドする方法について。
確か以前どこかで部分的に作成したテンプレートファイルの内容を参照する方法があったような気がするが、それには頼らずに自前でコントロール階層を構築してみる。
1. まず、新規に Webフォームを作成し、データグリッドを貼る。
※この時点で HTML ビューでのインデントが崩れるのはいかがなものか。
2. 適当なデータバインド列を作成し、テンプレート列に変換。
もちろん、最初からテンプレート列を書いてもいいのだが。
<%@ Page language="c#" Codebehind="test.aspx.cs" AutoEventWireup="false" Inherits="Web.test" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>test</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name=vs_defaultClientScript content="JavaScript">
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<asp:DataGrid id="DataGrid1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<asp:Label runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Foo") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Foo") %>' />
</EditItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</form>
</body>
</HTML>
3.
@IT ページから生成されたソース・コードを見るには?を参考に、
生成ソースが残るよう設定。
4. ソースを確認。
すると、
private System.Web.UI.Control __BuildControl__control5() {
System.Web.UI.WebControls.Label __ctrl;
__ctrl = new System.Web.UI.WebControls.Label();
this.__control5 = __ctrl;
__ctrl.DataBinding += new System.EventHandler(this.__DataBind__control5);
return __ctrl;
}
public void __DataBind__control5(object sender, System.EventArgs e) {
System.Web.UI.WebControls.DataGridItem Container;
System.Web.UI.WebControls.Label target;
target = ((System.Web.UI.WebControls.Label)(sender));
Container = ((System.Web.UI.WebControls.DataGridItem)(target.BindingContainer));
target.Text = System.Convert.ToString(DataBinder.Eval(Container.DataItem, "Foo"));
}
このあたりが対象かとわかる。
これと、元々の処理対象である ItemTemplate の処理とあわせると、
private void MakeColumn() {
TemplateColumn col = new TemplateColumn();
DataGrid1.Columns.Add(col);
col.ItemTemplate = new TestItemTemplate("Foo");
}
private class TestItemTemplate: ITemplate {
private string expression;
public TestItemTemplate(string expression) {
this.expression = expression;
}
#region ITemplate メンバ
public void InstantiateIn(Control container) {
Label label = new Label();
container.Controls.Add(label);
label.DataBinding += new EventHandler(this.LabelDataBinding);
}
#endregion
private void LabelDataBinding(object sender, EventArgs e) {
Label label = (Label)sender;
DataGridItem container = ((DataGridItem)(label.BindingContainer));
label.Text = Convert.ToString(DataBinder.Eval(container.DataItem, expression));
}
}
こんなのができた。