DataGrid是ASP.NET开发中最常用的控件之一,我们知道,DataGrid中的列包括绑定列,按钮列,超级连接列,模板列等类型,模板列当然是最复杂也最灵活的一种了。在一些项目中,我们需要在DataGrid中显示的列在开发阶段并不能确定,而将其留到了运行时。比如,我们要在DataGrid中显示一张工资表,而各个公司的工资项目并不相同,为适合各不同公司的需要,我们要让用户可以自定义工资项目,这时我们就需要动态创建列。下面的代码演示如何动态生成各种列。
一、绑定列(BoundColumn)
二、按钮列(ButtonColumn)
三、超级连接列(HyperLinkColumn)
四、模板列(TemplateColumn)
1
/// <summary>
2
/// 类 名 称:DataGridTextBoxTemplate
3
/// 内容摘要:文本框模板类
4
/// </summary>
5
public class DataGridTextBoxTemplate : ITemplate
6
{
7
// 数据列名
8
private string fieldName;
9
// 控件ID
10
private string ctrlID;
11![]()
12
/// <summary>
13
/// 构造方法
14
/// </summary>
15
/// <param name="strCtrlID">控件ID</param>
16
/// <param name="strFieldName">数据列名</param>
17
public DataGridTextBoxTemplate(string strCtrlID, string strFieldName)
18
{
19
fieldName = strFieldName;
20
ctrlID = strCtrlID;
21
}
22
23
/// <summary>
24
/// 实现ITemplate的InstantiateIn方法
25
/// </summary>
26
/// <param name="container">控件容器</param>
27
public void InstantiateIn(System.Web.UI.Control container)
28
{
29
TextBox tb = new TextBox();
30
tb.ID = ctrlID;
31
tb.Width = Unit.Percentage(100);
32
//tb.Text = "";
33
tb.DataBinding += new EventHandler(TextBoxTemplate_DataBinding);
34
container.Controls.Add(tb);
35
}
36
37
/// <summary>
38
/// 绑定事件处理
39
/// </summary>
40
/// <param name="sender"></param>
41
/// <param name="e"></param>
42
private void TextBoxTemplate_DataBinding(object sender, System.EventArgs e)
43
{
44
TextBox tb;
45
tb = (TextBox)sender;
46
DataGridItem container = (DataGridItem) tb.NamingContainer;
47
tb.Text += DataBinder.Eval(container.DataItem, fieldName);
48
//tb.Text += "</TD></TR>";
49
}
50
}
/// <summary>2
/// 类 名 称:DataGridTextBoxTemplate3
/// 内容摘要:文本框模板类4
/// </summary>5
public class DataGridTextBoxTemplate : ITemplate6
{ 7
// 数据列名8
private string fieldName;9
// 控件ID10
private string ctrlID;11

12
/// <summary>13
/// 构造方法14
/// </summary>15
/// <param name="strCtrlID">控件ID</param>16
/// <param name="strFieldName">数据列名</param>17
public DataGridTextBoxTemplate(string strCtrlID, string strFieldName)18
{19
fieldName = strFieldName;20
ctrlID = strCtrlID;21
}22
23
/// <summary>24
/// 实现ITemplate的InstantiateIn方法25
/// </summary>26
/// <param name="container">控件容器</param>27
public void InstantiateIn(System.Web.UI.Control container)28
{29
TextBox tb = new TextBox();30
tb.ID = ctrlID;31
tb.Width = Unit.Percentage(100);32
//tb.Text = "";33
tb.DataBinding += new EventHandler(TextBoxTemplate_DataBinding);34
container.Controls.Add(tb);35
}36
37
/// <summary>38
/// 绑定事件处理39
/// </summary>40
/// <param name="sender"></param>41
/// <param name="e"></param>42
private void TextBoxTemplate_DataBinding(object sender, System.EventArgs e)43
{44
TextBox tb;45
tb = (TextBox)sender;46
DataGridItem container = (DataGridItem) tb.NamingContainer;47
tb.Text += DataBinder.Eval(container.DataItem, fieldName);48
//tb.Text += "</TD></TR>";49
}50
}我们很快发现,这个DataGridTextBoxTemplate类只能适用于创建内部存放TextBox的模板列,如果按照这样的方式,我们需要创建一个CheckBox列就需要创建一个DataGridCheckBoxTemplate,需要创建一个DropDownList列就需要创建一个DataGridDropDownListTemplate类,这样的话,有多少控件就需要多少个模板类,显然,这样的类不具备通用性。
/// <summary>
/// 类 名 称:DataGridTemplate
/// 内容摘要:通用模板类
/// </summary>
public class DataGridTemplate : ITemplate
{
// 数据列名
private string fieldName;
// 控件值属性
private PropertyInfo valueProperty;
// 控件
private Control oCtrl;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="oControl">源控件</param>
/// <param name="ValueName">控件值属性的名称</param>
/// <param name="strFieldName">数据列名</param>
public DataGridTemplate(Control oControl, string ValueName, string strFieldName)
{
Type oType = oControl.GetType();
//PropertyInfo oPropertyInfo = oType.GetProperty(ValueName);
valueProperty = oType.GetProperty(ValueName);
oCtrl = oControl;
fieldName = strFieldName;
}
/// <summary>
/// 实现ITemplate的InstantiateIn方法
/// </summary>
/// <param name="container">控件容器</param>
public void InstantiateIn(System.Web.UI.Control container)
{
Control tmpCtrl = ControlClone(oCtrl);
tmpCtrl.DataBinding += new EventHandler(ControlTemplate_DataBinding);
container.Controls.Add(tmpCtrl);
}
/// <summary>
/// 绑定事件处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ControlTemplate_DataBinding(object sender, System.EventArgs e)
{
Control tmpCtrl;
tmpCtrl = (Control)sender;
DataGridItem container = (DataGridItem) tmpCtrl.NamingContainer;
try
{
string s = valueProperty.GetValue(tmpCtrl, null).ToString();
s += DataBinder.Eval(container.DataItem, fieldName);
valueProperty.SetValue(tmpCtrl , s ,null);
}
catch
{
}
}
/// <summary>
/// 复制控件
/// </summary>
/// <param name="oSource">源控件</param>
/// <returns></returns>
private Control ControlClone(Control oSource)
{
//创建复制品
Control oTarget = (Control)System.Activator.CreateInstance( oSource.GetType() );
//检查控件是否列表控件
ListControl oListControl = oSource as ListControl ;
if (oListControl != null) // 是列表控件
{
foreach (ListItem oItem in oListControl.Items) // 复制列表项
{
((ListControl)oTarget).Items.Add(new ListItem(oItem.Text , oItem.Value));
}
}
//将源对象的属性复制给复制品
Type oType = oSource.GetType() ;
// 复制控件属性
foreach (PropertyInfo oProperty in oType.GetProperties(BindingFlags.Instance| BindingFlags.Public ))
{
try
{
object oData = oProperty.GetValue(oSource, null);
oProperty.SetValue(oTarget , oData ,null);
}
catch{}
}

return oTarget;
}
}


浙公网安备 33010602011771号