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 }
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 }
我们很快发现,这个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;
}
}
/// 类 名 称: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;
}
}