如何在GRIDVIEW动态添加模板列,且提高可重用性
全部源代码如下,大家重点看标有 //★☆ 的两行。
我想提高代码的通用性,直接在 Page_Load 里面传一个控件进去,但是发现每行生成时都是指向同一个控件实例,结果导致GRIDVIEW创建后只有一行。如何能够深层克隆传进去的控件对象呢?
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
public class GridViewTemplate : ITemplate
{
private DataControlRowType _templateType;
private Control _control;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="type"></param>
/// <param name="colName"></param>
/// <param name="control"></param>
public GridViewTemplate( DataControlRowType type,
System.Web.UI.Control control)
{
_templateType = type;
_control = control;
}
public void InstantiateIn( System.Web.UI.Control container )
{
switch (_templateType)
{
case DataControlRowType.Header: //原来代码需要判断的,现在由于直接传 WebControl 进来,其实也不用判断了。
container.Controls.Add(_control);
break;
case DataControlRowType.DataRow:
System.Diagnostics.Debug.Print(_control.GetType().ToString());
//Label 等控件无法串列化,因此无法克隆
//byte[] bytes = ReadObject(_control);
//container.Controls.Add((Control)GetObject(bytes));
//★☆
container.Controls.Add(_control); //如果直接写这行,在每次实现 InstantiateIn 的时候永远是添加同一个控件实例的不同引用,无法在页面上显示多个控件(每行一个)
//如果直接在这里用以下代码创建新的Label就没问题
//Label lbl = new Label();
//lbl.ID = "lable1";
//lbl.Text = "dd";
//container.Controls.Add(lbl);
break;
default:
break;
}
}
private Byte[] ReadObject(object obj){
System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
bf.Serialize(ms, obj);
ms.Close();
return ms.ToArray();
}
private object GetObject(Byte[] bytes) {
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes,0,bytes.Length);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
return bf.Deserialize(ms);
}
}
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSourceID = "";
GridView1.PageSize = 20;
TemplateField customField = new TemplateField();
customField.ShowHeader = true;
Literal lit = new Literal();
lit.Text = "动态添加列1";
Label lbl = new Label();
lbl.ID = "lbl";
HyperLink hyp = new HyperLink();
hyp.ID = "ArticleURL";
hyp.Text = "ddd";
hyp.NavigateUrl = "http://test";
customField.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header,lit);
customField.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, lbl); //★☆
GridView1.Columns.Add(customField);
GridView1.DataSource = CreateDataSource(); //SqlDataSource1;
GridView1.DataBind();
}
}
/// <summary>
/// 临时生成一个数据源让GRIDVIEW 绑定
/// </summary>
/// <returns></returns>
private ICollection 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 < 6; i++)
{
dr = dt.NewRow();
dr[0] = i;
dr[1] = "列表项目 " + i.ToString();
dt.Rows.Add(dr);
}
DataView dv = new DataView(dt);
return dv;
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView gv = (DataRowView)e.Row.DataItem;
Label lbl = (Label)e.Row.FindControl("lbl");
lbl.Text = gv.Row["text"].ToString();
}
}
protected void GridView1_PageIndexChanged(object sender, EventArgs e)
{
}
}