C# 递归遍历OnInit中的控件将禁用GridView RowCommand并丢失Viewstate
如果递归遍历页面的控件,GridView中的LinkButtons将不再触发RowCommand事件。实际上,GridView的ViewState似乎丢失了。为什么?我怎样才能解决这个问题 在取消注释C# 递归遍历OnInit中的控件将禁用GridView RowCommand并丢失Viewstate,c#,asp.net,webforms,C#,Asp.net,Webforms,如果递归遍历页面的控件,GridView中的LinkButtons将不再触发RowCommand事件。实际上,GridView的ViewState似乎丢失了。为什么?我怎样才能解决这个问题 在取消注释//recurse(this.Controls)行之前,下面的代码可以正常工作。然后,当点击链接时,GridView将消失,并且永远不会触发RowCommand 我的页面的完整: <form id="form1" runat="server"> <asp:GridView
//recurse(this.Controls)
行之前,下面的代码可以正常工作。然后,当点击链接时,GridView将消失,并且永远不会触发RowCommand
我的页面的完整
:
<form id="form1" runat="server">
<asp:GridView ID="gv" AutoGenerateColumns="False" runat="server" onrowcommand="gv_RowCommand">
<Columns><asp:TemplateField HeaderText="Link"><ItemTemplate>
<asp:LinkButton ID="lnk" runat="server" CommandArgument = 'xxx'>xxx</asp:LinkButton>
</ItemTemplate></asp:TemplateField></Columns>
</asp:GridView>
</form>
@jbl为我找到了足够好的解释(感谢搜索技巧!)。这个问题以前在这里见过: 在初始化阶段以任何方式访问GridView的
.Controls
属性都会破坏其ViewState,从而总结该页面。原因没有任何解释,但人们还是观察到了这一点
这一页上有一个变通方法,对我来说已经足够好了。如果检查每个控件是否.HasControls()
,如果不检查,则不访问其.Controls
属性,ViewState不会丢失,因此事件将正常触发
另外,我猜这是一个bug,但当然,由于向后兼容,它不能永远更改:(您使用递归函数试图实现什么??在我的真实代码中,我正在按名称搜索一些控件,以便可以适当地设置它们的属性。OnInit中的代码正在清除它们。以后也可以访问它们(在加载等页面中),但这些递归搜索工作正常。你在哪里设置这些控件的属性?如果我们知道你想要实现什么,你可以给你另一种解决方案。@Magnus你不需要真正的递归函数来解释为什么这会导致问题。问题出在我给出的代码中。如果我知道原因,我可能可以我自己也有一个合理的解决办法。似乎你不是唯一一个有这个问题的人,明白吗
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//recurse(this.Controls);
}
private static void recurse(ControlCollection controls)
{
foreach (Control control in controls)
recurse(control.Controls);
}
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
var dt = new DataTable();
dt.Columns.Add("Link", typeof(string));
DataRow dr = dt.NewRow();
dr["Link"] = "google.com";
dt.Rows.Add(dt);
DataSet ds = new DataSet();
ds.Tables.Add(dt);
gv.DataSource = ds;
gv.DataBind();
}
}
protected void gv_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (this.Application["counter"] == null)
this.Application["counter"] = 0;
this.Application["counter"] = (int)this.Application["counter"] + 1;
Response.Write("JUNK" + this.Application["counter"]);
}