动态创建gridview的列

我在开发过程中发现有需要根据数据库传来的表的不同,产生不同的gridview的列,但是,其中根据数据表生成的列是要放到几个模板列之间的.前台代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="divGv" style="margin: 0 auto; text-align: center;" runat="server"> 
<asp:GridView ID="gvList" runat="server" AutoGenerateColumns="False" OnRowCommand="gvList\_RowCommand" OnRowCreated="gvList\_RowCreated" OnRowDataBound="gvList\_RowDataBound" DataKeyNames="id">
<Columns>
<asp:TemplateField>
<ItemTemplate>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="序号">
<ItemTemplate> </ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="管理">
<ItemTemplate></ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView> <webdiyer:AspNetPager ID="AspNetPager1" runat="server" ShowBoxThreshold="10" NumericButtonCount="8" OnPageChanging="AspNetPager1\_PageChanging" SubmitButtonClass="saveBtn"> </webdiyer:AspNetPager>
</div>

后台代码相当多,可能有人说为什么前台里的模板列里没有控件呢?这个是因为我现在要做的是插入列,使用的是insert,如果是使用了add,那么这个是可以直接在前台完全写好模板列的,也没有下面的这么麻烦了,贴出后台代码,希望有人可以给出更简单的办法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//创建及设置字段 
public void setfields() {
int recordCount = 0; string tabname = getTabName();
//取得一次分页数据,以用来确定列
string where="where 1=1";
DataTable dt = ColumnConfigerInfo.GetValueByTableName(AspNetPager1.PageSize,AspNetPager1.CurrentPageIndex,tabname,where,out recordCount);
//设置总记录数
AspNetPager1.RecordCount = recordCount;
int num = dt.Columns.Count;
//循环插入列,并绑定字段
for (int i = 3; i < num; i++) {
BoundField cc = new BoundField();
cc.DataField = dt.Columns[i].ColumnName;
cc.HeaderText = dt.Columns[i].ColumnName;
cc.ItemStyle.Wrap = false; //
if(dt.Columns[i\].ColumnName.Equals("外键"))
{
    //隐藏掉该列
   cc.Visible = false;
}
//判断是否是时间类型的列
if (dt.Columns[i].DataType.Name == "DateTime") {
//设置时间格式
cc.DataFormatString = "{0:yyyy-MM-dd}"; cc.HtmlEncode = false; } cc.ReadOnly = true; gvList.Columns.Insert(i-1, cc);
}
//绑定分页控件,数据源,
Gridview,aspnetpager UI.BindCtrl(recordCount, dt.DefaultView, gvList, AspNetPager1); }
/// <summary>
/// 取得表名
/// </summary>
/// <returns></returns>
private string getTabName() {
int tabid = int.Parse(lbltabId.Text);
TableDetailInfo tab = new TableDetailInfo(tabid);
string tabname = tab.TableName;
return tabname;
}
     看到这里,是不是觉得很简单呢?错了.麻烦的在后面呢.这个使用了列的insert方法后,进行翻页的时候模板列如果本来在前台写了控件的就会消失,这个还不知道原因,网上找了找,据说是微软的bug.所以我追加下面的代码来解决这个问题 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
         //行创建时候添加模板列的控件 
protected void gvList_RowCreated(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.Header) {
int cc = gvList.Columns.Count;
CheckBox cb = new CheckBox();
cb.ID = "ckbAll";
e.Row.Cells[0].Controls.Add(cb);
cb.AutoPostBack = true;
cb.CheckedChanged += new EventHandler(cb_CheckedChanged); }
if (e.Row.RowType == DataControlRowType.DataRow) {
int cc=gvList.Columns.Count;
CheckBox ckb = new CheckBox();
ckb.ID = "ckbDetail";
e.Row.Cells[0].Controls.Add(ckb);
LinkButton lbtn1 = new LinkButton();
lbtn1.Text = " [收藏] ";
lbtn1.CommandName = "collect";
e.Row.Cells[cc - 1].Controls.Add(lbtn1);
lbtn1.CommandArgument = e.Row.RowIndex.ToString();
LinkButton lbtn2 = new LinkButton();
lbtn2.CommandName = "attention";
e.Row.Cells[cc - 1].Controls.Add(lbtn2); lbtn2.Text = " [中标] "; lbtn2.CommandArgument = e.Row.RowIndex.ToString();
LinkButton lbtn3 = new LinkButton();
lbtn3.CommandName = "compare";
e.Row.Cells[cc - 1].Controls.Add(lbtn3);
lbtn3.Text = " [比对] ";
lbtn3.CommandArgument = e.Row.RowIndex.ToString();
LinkButton lbtn4 = new LinkButton();
lbtn4.CommandName = "detail";
e.Row.Cells[cc - 1].Controls.Add(lbtn4);
lbtn4.Text = " [查看详细] ";
lbtn4.CommandArgument = e.Row.RowIndex.ToString(); } }

其中类似lbtn4.CommandArgument = e.Row.RowIndex.ToString();的代码是绑定行值,以方便后面进行操作 而

1
2
3
4
5
6
7
8
if (e.Row.RowType == DataControlRowType.Header) {
int cc = gvList.Columns.Count;
CheckBox cb = new CheckBox();
cb.ID = "ckbAll";
e.Row.Cells[0].Controls.Add(cb);
cb.AutoPostBack = true;
cb.CheckedChanged += new EventHandler(cb_CheckedChanged);
}

则是为了生成全选按钮,并订阅CheckedChanged事件.以用来激发下面的事件,来全选上所有复选框

1
2
3
4
5
6
7
8
9
10
protected void cb_CheckedChanged(object sender, EventArgs e) { 
for (int i = 0; i < gvList.Rows.Count; i++) {
CheckBox ckb = (CheckBox)gvList.Rows[i].Cells[0].Controls[0] as CheckBox; CheckBox ckbAll = sender as CheckBox;
if (ckbAll.Checked) {
ckb.Checked = true;
} else {
ckb.Checked = false;
}
}
}