C# 递归遍历OnInit中的控件将禁用GridView RowCommand并丢失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

如果递归遍历页面的控件,GridView中的LinkButtons将不再触发RowCommand事件。实际上,GridView的ViewState似乎丢失了。为什么?我怎样才能解决这个问题

在取消注释
//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"]);
    }