转http://blog.csdn.net/yuanfang8789/archive/2007/08/17/1748554.aspx
近日在做GridView动态加载模板列的问题是,发现微软的GridView功能竟然如此捉襟见肘。本来想一个AddColumn()即可搞定的问题,到现实中却发现,远非想像中的那般美好。。。。。
于是在网上查了相关的示例,发现都只泛泛讲了一下原理,真正可实用的没有发现,所以一狠心,整理了一下这方面的代码,写了一个派生类。在只使用TextBox模板列的情况下还可以满足要求,至少满足我的要求了。各位可以根据需要扩展即可。本人菜鸟一个,不求甚解,只为实现功能,望高人多多指点。
/// <summary>
/// GridView动态模板列
/// </summary>
/// <example>
/// TemplateFieldEx te = new TemplateFieldEx(150, "动态添加列", "idddd", "id", false);
/// GridView1.Columns.Add(te);
/// </example>
public class TemplateFieldEx : TemplateField
{
/// <summary>
/// 此无参构造必须实现,否则出错
/// </summary>
public TemplateFieldEx()
:base()
{
}
/// <summary>
/// 构造模板列,具体样式请在GridView中直接设置
/// </summary>
/// <param name="nWidth">当前列限定宽度</param>
/// <param name="strColumnText">标题字符串</param>
/// <param name="strTxtID">插入的编辑框ID,注意勿重复</param>
/// <param name="strField">当前弄绑定的字段</param>
/// <param name="bReadOnly">编辑框是否只读</param>
public TemplateFieldEx(int nWidth, string strColumnText, string strTxtID, string strField, bool bReadOnly):
base()
{
this.ControlStyle.Width = Unit.Pixel(nWidth);
this.ItemStyle.Width = Unit.Pixel(nWidth);
this.ShowHeader = true;
this.HeaderTemplate = new GridViewItemTemplate(strColumnText);
this.ItemTemplate = new GridViewItemTemplate(strTxtID, strField, bReadOnly);
}
}
/// <summary>
/// GridView模板项
/// </summary>
public class GridViewItemTemplate : ITemplate
{
private DataControlRowType m_type;
private bool m_bReadOnly;
private string m_strTxtID;
private string m_strColumnText;
private string m_strField;
/// <summary>
/// 此无参构造必须实现,否则出错
/// </summary>
public GridViewItemTemplate() : base()
{
}
/// <summary>
/// 构造表头列对象
/// </summary>
/// <param name="strColumnText">表头字符串</param>
public GridViewItemTemplate(string strColumnText)
{
m_type = DataControlRowType.Header;
m_strColumnText = strColumnText;
}
/// <summary>
/// 构造元素行对象
/// </summary>
/// <param name="strTxtID">当前TextBox控件ID</param>
/// <param name="strField">当前TextBox控件绑定的字段</param>
/// <param name="bReadOnly">TextBox是否只读</param>
public GridViewItemTemplate(string strTxtID, string strField, bool bReadOnly)
{
m_type = DataControlRowType.DataRow;
m_strTxtID = strTxtID;
m_strField = strField;
m_bReadOnly = bReadOnly;
}
public void InstantiateIn(System.Web.UI.Control container)
{
switch (m_type)
{
case DataControlRowType.Header:
Literal l = new Literal();
l.Text = m_strColumnText;
container.Controls.Add(l);
break;
case DataControlRowType.DataRow:
TextBox tb = new TextBox();
tb.ID = m_strTxtID;
tb.Width = Unit.Percentage(100);
tb.BorderStyle = BorderStyle.None;
tb.DataBinding += new EventHandler(TextBox_DataBinding);
tb.ReadOnly = m_bReadOnly;
container.Controls.Add(tb);
break;
default:
break;
}
}
private void TextBox_DataBinding(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
GridViewRow gvr = tb.NamingContainer as GridViewRow;
tb.Text = DataBinder.Eval(gvr.DataItem, m_strField).ToString();
}
}
示例代码如下:
protected void Page_Load(object sender, EventArgs e)
{
// 注意此处不可放在if(!IsPostBack)中,否则任何一个PostBack命令将会导致此模板列数据丢失,不知何故??
PerformDataBind();
}
private void PerformDataBind()
{
// 注意:此处需要删除列,否则重新添加会导致模板列数量增加
GridView1.Columns.Clear();
TemplateFieldEx te = new TemplateFieldEx(150, "动态添加列", "t1", "id", false);
GridView1.Columns.Add(te);
te = new TemplateFieldEx(150, "text", "t2", "text", true);
GridView1.Columns.Add(te);
GridView1.DataSource = CreateDataSource();
GridView1.DataBind();
}
/// <summary>
/// 构造数据源
/// </summary>
/// <returns></returns>
DataTable CreateDataSource()
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new DataColumn("id", typeof(Int32)));
dt.Columns.Add(new DataColumn("text", typeof(string)));
for (int i = 0; i < 16; i++)
{
dr = dt.NewRow();
dr[0] = i;
dr[1] = "列表项目 " + i.ToString();
dt.Rows.Add(dr);
}
return dt;
}
protected void Button1_Click(object sender, EventArgs e)
{
// 读取TextBox控件内容
TextBox t = GridView1.Rows[0].Cells[0].FindControl("t1") as TextBox;
// 如果需要,重新绑定之
PerformDataBind();
}
界面代码如下:
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<HeaderStyle BackColor="#C0C0FF" />
</asp:GridView>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /></div>
</form>