GridView 中模板列莫名其妙消失
问题描述:Gridvie控件有一个固定的模板列,其它列都是动态添加的,包括ButtonField列.当我加载数据的时候,一切正常,但是当点击GridView中翻页后,模板列消失了,模板列的表头还在,就是内容消失了.其它列都没有问题.
代码如下:
<asp:GridView ID="GvSelectResult" PageSize="20" runat="server" AllowPaging="True" Width="1500"
BackColor="White" BorderColor="#A6CBEF" BorderStyle="Solid" BorderWidth="1px"
OnPageIndexChanging="GvSelectResult_PageIndexChanging" AutoGenerateColumns="False" OnRowCommand="GvSelectResult_RowCommand" OnRowDataBound="GvSelectResult_RowDataBound" OnRowCreated="GvSelectResult_RowCreated">
<Columns>
<asp:TemplateField HeaderText="<input id='Checkbox1' type='checkbox' onclick='selectAll(this)' />" >
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
public void addButtonField(string headText, string text, string cmdName)
{
ButtonField bf = new ButtonField();
bf.HeaderText = headText;
bf.Text = text;
bf.CommandName = cmdName;
GvSelectResult.Columns.Insert(0,bf);
}
public void addHyperLinkField(string headText, string text,
string[] DataNavigateUrlFields, string DataNavigateUrlFormatString, string Target)
{
HyperLinkField hlf = new HyperLinkField();
hlf.HeaderText = headText;
hlf.Text = text;
hlf.Target = Target;
hlf.DataNavigateUrlFields = DataNavigateUrlFields;
hlf.DataNavigateUrlFormatString = DataNavigateUrlFormatString;
GvSelectResult.Columns.Insert(0,hlf);
}
protected void Page_Init(object sender, EventArgs e)
{
DataSet reportKey, GvDataSet;
reportKey = new DataSet();
GvDataSet = new DataSet();
if (!String.IsNullOrEmpty(bbid))
{
reportKey = DbOperateClass.DbOperate.GetDataSet("select tablename,zdm,zwhy from zdybb where bbid='"
+ bbid + "' and yxbz='1' order by zdxssx");
string tableName;
DataTableReader dtr = new DataTableReader(reportKey.Tables[0]);
DataTableReader dtr1 = new DataTableReader(reportKey.Tables[0]);
DataTableReader dtr2 = new DataTableReader(reportKey.Tables[0]);
StringBuilder sb = new StringBuilder("select ");
try
{
dtr1.Read();
tableName = dtr1.GetString(0);
while (dtr.Read())
{
sb.Append(dtr.GetString(1));
sb.Append(",");
}
}
finally
{
dtr1.Close();
dtr.Close();
}
sb.Length = sb.Length - 1;
sb.Append(" from ");
sb.Append(tableName);
ViewState["selectSql"] = sb.ToString();//保存查询命令
GvDataSet = DbOperateClass.DbOperate.GetDataSet(sb.ToString());
GvDataSet.Tables[0].TableName = tableName;
string[] colName = new string[GvDataSet.Tables[0].Columns.Count];
for (int i = 0; dtr2.Read();i++ )//给数据源加上中文列名
{
GvDataSet.Tables[0].Columns[i].Caption = dtr2.GetString(2);
colName[i] = GvDataSet.Tables[0].Columns[i].ColumnName;
}
this.DataTableKeys = colName;//获取字段的名字
}
Ds = GvDataSet;//设置控件的数据源
if (GvDataSet.Tables[0].Rows.Count > 0)
{
if (gvPageSize != 0)
{
GvSelectResult.PageSize = gvPageSize;//根据属性设置GridView的分页数据
}
if (dataKey.Length > 0)
{
GvSelectResult.DataKeyNames = new string[] { dataKey };//设置GridView的主键
}
if (!Page.ClientScript.IsClientScriptIncludeRegistered(this.GetType(), "checkAll"))
{
Page.ClientScript.RegisterClientScriptInclude("checkAll", Page.ResolveClientUrl("~/script/GridView.js"));
}
if (!Page.IsPostBack)
{
DbOperateClass.DbOperate.dynamicGenerateColumns(GvSelectResult, ds.Tables[0]);
for (int p = 0; p < ds.Tables[0].Columns.Count; p++)//给gv命名列名称
{
GvSelectResult.Columns[p + 1].HeaderText = ds.Tables[0].Columns[p].Caption;
//GvSelectResult.HeaderRow.Cells[p].Text = ds.Tables[0].Columns[p].Caption;
}
addCheckBoxCol();
//LabTableName.Text = ds.Tables[0].TableName;
for (int p = 0; p <= ds.Tables[0].Columns.Count; p++)
{
if (p == ds.Tables[0].Columns.Count)
{
R1C1.Items.Insert(0, new ListItem("", ""));
break;
}
ListItem li = new ListItem(ds.Tables[0].Columns[p].Caption, ds.Tables[0].Columns[p].ColumnName);
R1C1.Items.Add(li);
}
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (ds.Tables[0].Rows.Count>0)
{
GridViewDataBind(GvSelectResult, ds); //执行数据绑定
}
}
}
上面我贴出了动态添加列的方法,和page_load,page_Init,页面东西比较多我就贴出这么多,需要的话我再贴.最后一点,我动态添加列的话,如果是用的 add()方法,而不是用insert()方法的话,不会出现任何问题,使用insert()方法指定动态添加列的位置后,就出现了,翻页后,模板列内容消失的问题.
在baidu上搜索了好久,也没有找到答案,包括在社区里面.大家在baidu搜索这个问题的帮助时,注意一下病毒,有一个页面有利用realplay漏洞的病毒,我的机器中招了,删除不干净,就是usrinit.exe这个鸟东西.
[解决办法]
项贴,我也想知道怎么解决这个问题!
[解决办法]
好多人说就是在数据库里绑定一个空白数据行!但是......
[解决办法]
帮顶一下 楼主的代码怎么这么写的
[解决办法]
翻页后动态的添加状态就丢失了
[解决办法]
翻页后动态的添加状态就丢失了
[解决办法]
看样子我不太适合技术,不喜欢研究,只要求能做出来就好的那种...
[解决办法]
UP
------解决方案--------------------
up
[解决办法]
UP
[解决办法]
MARK!
[解决办法]
动态添加绑定列后一定要在GridView1_RowDataBound进行从新绑定:
HTML:
-------------------------------------------------------
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="选择">
<ItemTemplate>
<%--<asp:CheckBox ID="CheckBox1" runat="server" Style="position: relative" />--%>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Name" HeaderText="name" />
<asp:BoundField DataField="sale" HeaderText="sale" />
<asp:TemplateField HeaderText="单选">
<ItemTemplate>
<%--<asp:RadioButton ID="RadioButton1" runat="server" AutoPostBack="True" GroupName="d"
Style="position: relative" />
<asp:RadioButton ID="RadioButton2" runat="server" AutoPostBack="True" GroupName="d"
OnCheckedChanged="RadioButton2_CheckedChanged" Style="position: relative" />--%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="下拉">
<ItemTemplate>
<%--<asp:DropDownList ID="DropDownList1" runat="server" Style="position: relative">
</asp:DropDownList>--%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Style="position: relative"
Text="Button" />
</form>
C#:
------------------------------------------
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BoundField te = new BoundField();
te.HeaderText = "Date";
te.DataField = "dd";
GridView1.Columns.Insert(1, te);
}
Bind();
}
public void Bind()
{
SqlConnection con = new SqlConnection("server=.;uid=sa;pwd=;database=Demo");
string sql = "select * from test";
SqlDataAdapter da = new SqlDataAdapter(sql, con);
DataSet ds = new DataSet();
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
int rownum = GridView1.Rows.Count;
int colnum = GridView1.Columns.Count;
foreach (GridViewRow gvr in GridView1.Rows)
{
//for (int i = 0; i < gvr.Controls.Count; i++)
//{
// for (int j = 0; j < gvr.Controls[i].Controls.Count; j++)
// {
// int aaa = 0;// gvr.Controls[i].ID;
// }
//}
CheckBox chk = (CheckBox)gvr.FindControl("CheckBox1");
if (chk.Checked)
{
Response.Write(gvr.Cells[1].Text);
}
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
CheckBox chk = new CheckBox();
chk.ID = "CheckBox1";
e.Row.Cells[0].Controls.Add(chk);
RadioButton rbtn1 = new RadioButton();
rbtn1.ID = "RadioButton1";
rbtn1.AutoPostBack = true;
rbtn1.GroupName = "dan";
RadioButton rbtn2 = new RadioButton();
rbtn2.ID = "RadioButton2";
rbtn2.AutoPostBack = true;
rbtn2.GroupName = "dan";
e.Row.Cells[4].Controls.Add(rbtn1);
e.Row.Cells[4].Controls.Add(rbtn2);
rbtn1.CheckedChanged += new EventHandler(rbtn1_CheckedChanged);
rbtn2.CheckedChanged += new EventHandler(rbtn2_CheckedChanged);
DropDownList ddl = new DropDownList();
ddl.ID = "DropDownList1";
e.Row.Cells[5].Controls.Add(ddl);
}
}
void rbtn1_CheckedChanged(object sender, EventArgs e)
{
foreach (GridViewRow gvr in GridView1.Rows)
{
RadioButton rbtn = (RadioButton)gvr.FindControl("RadioButton1");//第二个
if (rbtn.Checked)
{
DropDownList ddl = (DropDownList)gvr.FindControl("DropDownList1");
ddl.Visible = true;
}
}
}
void rbtn2_CheckedChanged(object sender, EventArgs e)
{
foreach (GridViewRow gvr in GridView1.Rows)
{
RadioButton rbtn = (RadioButton)gvr.FindControl("RadioButton2");//第二个
if (rbtn.Checked)
{
DropDownList ddl = (DropDownList)gvr.FindControl("DropDownList1");
ddl.Visible = false;
}
}
}
SQL:
------------------------------------------
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[test]
GO
CREATE TABLE [dbo].[test] (
[name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[sale] [int] NULL ,
[dd] [datetime] NULL
) ON [PRIMARY]
GO
[解决办法]
再告诉你怎么插入模板列并定位模板列中下拉列表每项的selectindex的两种方法:(用的是sqlserver2000的pubs库)
动态添加模板列方法一:
HTML:
-----------------------------------------------------
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="au_id"
OnRowDataBound="GridView1_RowDataBound" Style="position: relative">
<Columns>
<asp:BoundField DataField="au_id" HeaderText="ID" />
<asp:BoundField DataField="au_fname" HeaderText="名字" />
</Columns>
</asp:GridView>
</div>
</form>
C#:
------------------------------------------------------
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TemplateField tf = new TemplateField();
tf.ShowHeader = true;
tf.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "动态添加模板列");
tf.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "");
GridView1.Columns.Add(tf);
GetDataSource();
}
}
#region//获取绑定数据源
public void GetDataSource()
{
SqlConnection con = new SqlConnection("server=.;uid=sa;pwd=;database=pubs");
SqlDataAdapter da = new SqlDataAdapter("select au_id,au_fname from authors", con);
DataSet ds = new DataSet();
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
}
#endregion
#region//嵌套类,用来把要绑定的下拉列表填充好
public class GridViewTemplate : ITemplate
{
private DataControlRowType templateType;
private string columnName;
//为新添加的列赋值
public GridViewTemplate(DataControlRowType type, string colname)
{
templateType = type;
columnName = colname;
}
//实现接口方法,把DropDownList填充到容器中
public void InstantiateIn(System.Web.UI.Control container)
{
switch (templateType)
{
case DataControlRowType.Header:
Literal lc = new Literal();
lc.Text = columnName;
container.Controls.Add(lc);
break;
case DataControlRowType.DataRow:
//填充并向模板列中添加DropDownList控件
DropDownList ddl = new DropDownList();
ddl.ID = "DropDownList1";
ddl.AppendDataBoundItems = true;
SqlConnection conC = new SqlConnection("server=.;uid=sa;pwd=;database=pubs");
SqlDataAdapter daC = new SqlDataAdapter("select Distinct(state) from authors", conC);
DataSet dsC = new DataSet();
daC.Fill(dsC);
DataView dvC = new DataView(dsC.Tables[0]);
conC.Close();
ddl.DataSource = dvC;
ddl.DataTextField = "state";
ddl.DataValueField = "state";
ddl.DataBind();
/*
* 如果用这种写法绑定ddl的话,必须要注释掉最后两行的关闭连接的方法,不然会报错,所以不安全
SqlCommand comC = new SqlCommand("select Distinct(state) from authors", conC);
conC.Open();
SqlDataReader drC = comC.ExecuteReader();
ddl.DataSource = drC;
ddl.DataTextField = "state";
ddl.DataValueField = "state";
ddl.DataBind();
//drC.Close();
//conC.Close();
*/
container.Controls.Add(ddl);
break;
default:
break;
}
}
}
#endregion
#region//绑定列事件,找到每个主键分别对应的州
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = (DropDownList)e.Row.FindControl("DropDownList1");
string stateIndex = DropIndex(e.Row.Cells[0].Text);
ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByText(stateIndex));
}
}
#endregion
#region//寻找主键对应的州
public string DropIndex(string sqltj)
{
string stateIndex = "";
//先通过传递过来的主键找到他所对应的州
SqlConnection conC = new SqlConnection("server=.;uid=sa;pwd=;database=pubs");
SqlCommand comC = new SqlCommand("select state from authors where au_id='" + sqltj + "'", conC);
conC.Open();
SqlDataReader drC = comC.ExecuteReader();
if (drC.Read())
{
stateIndex = drC["state"].ToString();
}
drC.Close();
conC.Close();
return stateIndex;
}
#endregion
[解决办法]
你自己比较一下这两种方法吧,代码都给你了 我就不细讲了
动态添加模板列方法二:
HTML:
----------------------
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="au_id"
OnRowDataBound="GridView1_RowDataBound" Style="position: relative">
<Columns>
<asp:BoundField DataField="au_id" HeaderText="ID" />
<asp:BoundField DataField="au_fname" HeaderText="名字" />
<asp:TemplateField HeaderText="下拉列表列"></asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
C#:
----------------------
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetDataSource();
}
}
#region//获取绑定数据源
public void GetDataSource()
{
SqlConnection con = new SqlConnection("server=.;uid=sa;pwd=;database=pubs");
SqlDataAdapter da = new SqlDataAdapter("select au_id,au_fname from authors", con);
DataSet ds = new DataSet();
da.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
}
#endregion
#region//绑定列事件,找到每个主键对应的州
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl = new DropDownList();
ddl.ID = "DropDownList1";
SqlConnection conC = new SqlConnection("server=.;uid=sa;pwd=;database=pubs");
SqlCommand comC = new SqlCommand("select Distinct(state) from authors", conC);
conC.Open();
SqlDataReader drC = comC.ExecuteReader();
ddl.DataSource = drC;
ddl.DataTextField = "state";
ddl.DataValueField = "state";
ddl.DataBind();
drC.Close();
conC.Close();
string stateIndex = DropIndex(e.Row.Cells[0].Text);
ddl.SelectedIndex = ddl.Items.IndexOf(ddl.Items.FindByText(stateIndex));
e.Row.Cells[2].Controls.Add(ddl);
}
}
#endregion
#region//寻找主键对应的州
public string DropIndex(string sqltj)
{
string stateIndex = "";
//先通过传递过来的主键找到他所对应的州
SqlConnection conC = new SqlConnection("server=.;uid=sa;pwd=;database=pubs");
SqlCommand comC = new SqlCommand("select state from authors where au_id='" + sqltj + "'", conC);
conC.Open();
SqlDataReader drC = comC.ExecuteReader();
if (drC.Read())
{
stateIndex = drC["state"].ToString();
}
drC.Close();
conC.Close();
return stateIndex;
}
#endregion
[解决办法]
代码写的好乱!!
找别人的程序看看吧
你这个问题应该是数据绑定的问题.当你点第二页时,数据没有取到,当然就消失了!
------解决方案--------------------
代码看过了,可惜我刚开始搞asp.net等我研究研究先
[解决办法]
ls的兄弟不用那么生气吧,我看了你2个方法觉得确实学到不少东西。但是第2个只能叫动态添加控件吧
[解决办法]
其实解决问题的办法可能有很多种,我们只是碰巧一样罢了,好了不说这个了。
不管会不会消失,如果是追加进来的控件,最好还是要在GridView1_RowDataBound()事件中从新绑定一下 比较安全,因为毕竟是咱们手动加进来的
[解决办法]
手动加的列,是在每次生成GV的PAGE时用你的函数生成的。
自动生成的列包括模板列要在DataBind后生成。调试的时候能看到这个过程。在<%%>中可以加个断点