一、動態添加模板列:
1、建立模板列樣式:
說明:下邊代碼可以直接寫在aspx文件中,也可以單獨建立cs文件;另外,我沒有寫button、linkButton等控件,意思差不多,不過當需要添加事件時,記得將事件名稱傳入,並附加在控件上
public class GridViewTemplate : ITemplate
{
/// <summary>
/// 模板類型:標題或內容;
/// DataControlRowType.Header和DataControlRowType.DataRow
/// </summary>
private DataControlRowType P_TemplateType;
/// <summary>
/// 列的名稱:列標題時,為列顯示名稱;列內容時,為列的字段名稱
/// </summary>
private string P_ColumnName;
/// <summary>
/// 列的類型:TextBox、DropDownList等
/// </summary>
private string P_ColumnType;
public GridViewTemplate()
{
//
//TODO: 在此處添加構造函數邏輯
//
}
/// <summary>
/// 構造函數:動態添加模版列
/// </summary>
/// <param name="TemplateType">模板類型:標題或內容;DataControlRowType.Header和DataControlRowType.DataRow</param>
/// <param name="ColumnName">列的名稱:列標題時,為列顯示名稱;列內容時,為列的字段名稱</param>
/// <param name="ColumnType">列的類型:列標題時,可為空;列內容時,為模板列的控件類型</param>
public GridViewTemplate(DataControlRowType TemplateType, string ColumnName, string ColumnType)
{
P_TemplateType = TemplateType;
P_ColumnName = ColumnName;
P_ColumnType = ColumnType;
}
public void InstantiateIn(System.Web.UI.Control container)
{
switch (P_TemplateType)
{
case DataControlRowType.Header://列標題
Literal lc = new Literal();
lc.Text = P_ColumnName;
container.Controls.Add(lc);
break;
case DataControlRowType.DataRow://模版列內容
if (P_ColumnType.ToUpper() == "TextBox".ToUpper())
{
TextBox tb = new TextBox();
tb.ID = "txt_" + P_ColumnName;
tb.AutoPostBack = true;
tb.EnableViewState = true;
//tb.Text = "";
tb.DataBinding += new EventHandler(tb_DataBinding);
container.Controls.Add(tb);
}
else if (P_ColumnType.ToUpper() == "Label".ToUpper())
{
System.Web.UI.WebControls.Label lb = new Label();
lb.ID = "lbl_" + P_ColumnName;
lb.EnableViewState = true;
//tb.Text = "";
lb.DataBinding += new EventHandler(lb_DataBinding);
container.Controls.Add(lb);
}
else
{ //默認為TextBox
TextBox tb = new TextBox();
tb.ID = "txt_" + P_ColumnName;
tb.AutoPostBack = true;
tb.EnableViewState = true;
tb.DataBinding += new EventHandler(tb_DataBinding);
container.Controls.Add(tb);
}
break;
default:
break;
}
}
void tb_DataBinding(object sender, EventArgs e)
{
TextBox txtdata = (TextBox)sender;
GridViewRow container = (GridViewRow)txtdata.NamingContainer;
object dataValue = DataBinder.Eval(container.DataItem, P_ColumnName);
if (dataValue != DBNull.Value)
{
txtdata.Text = dataValue.ToString();
}
}
void lb_DataBinding(object sender, EventArgs e)
{
Label lbldata = (Label)sender;
GridViewRow container = (GridViewRow)lbldata.NamingContainer;
object dataValue = DataBinder.Eval(container.DataItem, P_ColumnName);
if (dataValue != DBNull.Value)
{
lbldata.Text = dataValue.ToString();
}
}
}
2、前台aspx文件:
<asp:GridView ID="gvData" runat="server" SkinID="GridView" Width="100%" UseAccessibleHeader="False"
AutoGenerateColumns="False" AllowPaging="True"
PageSize="100" onload="gvData_Load" >
<PagerSettings Visible="False" />
<HeaderStyle Font-Bold="True" />
</asp:GridView>
3、aspx.cs文件--創建GridView,並綁定數據:
說明:dt是外部獲取的數據,我是根據數據表,動態生成GridView,並賦值
private void CreateDT(DataTable dt)
{
this.gvData.Columns.Clear();
TemplateField customField = new TemplateField();
for (int i = 0; i < dt.Columns.Count; i++)
{
customField = new TemplateField();
customField.ShowHeader = true;
customField.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, dt.Columns[i].ColumnName, "");
customField.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, dt.Columns[i].ColumnName, "TextBox");
ViewState["txt_" + dt.Columns[i].ColumnName] = true;
gvData.Columns.Add(customField);
}
//綁定數據
this.gvData.DataSource = dt;
this.gvData.DataBind();
}
4、aspx.cs文件:重復建立並綁定數據,因為動態生成控件時,只要有刷新,所有的動態控件就全部消失,所以需要每次刷新都要重新綁定一次;
另外,我試過在OnInit、gvData_Init等事件中執行建立並綁定數據的操作,都可以實現,但是對於我不大適用,因為我是根據TreeView的選中項,來創建綁定GridView的;其他事件執行時機靠前,無法獲取TreeView的選中項是哪個,而gvData_Load事件可以(雖然該事件也是在TreeView選中事件前執行,不過並不影響選中項的變化和獲取到的內容)
protected void gvData_Load(object sender, EventArgs e)
{
DataTable dt=GetData();
CreateDT(dt);
}
5、aspx.cs文件:點擊按鈕,獲取前台修改過的gvData中模板列的數據:
說明:我的保存時,先將數據保存進ViewState["DtData"]后,再執行保存功能;這么做是因為別的頁面的問題,需要獲取后,再刷新;不過大致意思都是相同的
注意:也可以使用TextBox txt= (TextBox)gvData.Rows[i].FindControl("txt_"+dtData.Columns[j].ColumnName);獲取
private void SaveToTable()
{
DataTable dtData = (DataTable)ViewState["DtData"];
for (int i = 0; i < this.gvData.Rows.Count; i++)
{
for (int j = 0; j < dtData.Columns.Count; j++)
{
string txtName = "gvData$ctl" + (i + 2).ToString().PadLeft(2, '0') + "$txt_" + dtData.Columns[j].ColumnName;
if (Request.Form[txtName] != null)
{//目前僅能通過這個判斷
dtData.Rows[i][j] = Request.Form[txtName];
JsService.ResponseMessage(this.UpdatePanel1, this.GetType(), "txtName:" + txtName + "----" + Request.Form[txtName]);
break;
}
}
}
ViewState["DtData"] = dtData;
}
6、實際上最主要的再gvData_Load事件中重復的動態創建並獲取數據.