递归遍历 OnInit 中的控件禁用 GridView RowCommand 并丢失 Viewstate [英] Recursively traversing controls In OnInit disables GridView RowCommand and loses Viewstate

查看:20
本文介绍了递归遍历 OnInit 中的控件禁用 GridView RowCommand 并丢失 Viewstate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我递归遍历页面的控件,GridView 中的 LinkBut​​ton 将不再触发 RowCommand 事件.实际上,GridView 的 ViewState 似乎丢失了.为什么?我该如何解决这个问题?

If I recursively traverse the controls of a page, the RowCommand event is no longer fired by LinkButtons in a GridView. In fact, it looks like the ViewState for the GridView is lost. Why? How can I work around this?

在您取消注释 //recurse(this.Controls) 行之前,下面的代码将正常工作.然后,当您点击链接时,GridView 消失并且 RowCommand 永远不会被触发.

The code below will work fine until you uncomment the //recurse(this.Controls) line. Then, when you hit the link, the GridView disappears and the RowCommand is never fired.

我页面的完整:

<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>

我背后的代码:

    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"]);
    }

推荐答案

@jbl 找到了一些对我来说足够好的解释(感谢搜索技巧!).这个问题以前在这里见过:http://forums.asp.net/t/1043999.aspx/1

@jbl found something that explained this well enough for me (thanks for the search skills!). This problem has been seen before here: http://forums.asp.net/t/1043999.aspx/1

总结该页面,在 Init 阶段以任何方式访问 GridView 的 .Controls 属性将破坏其 ViewState.没有解释为什么,但无论如何都观察到了.

Summarizing that page, accessing the .Controls property of a GridView in any way during the Init phase will destroy its ViewState. There is no explanation for why, but it has been observed anyway.

该页面上有一个对我来说足够好的解决方法.如果您检查每个控件以查看它是否 .HasControls() 并且如果不是,则不访问其 .Controls 属性,则 ViewState 不会丢失,因此事件将正常触发.

There is a workaround on that page that is good enough for me. If you check for each control to see if it .HasControls() and don't access its .Controls property if it doesn't, the ViewState will not be lost, and consequently events will fire normally.

附言我猜这是一个错误,但当然由于向后兼容性,它不能永远改变:(

P.S. I'm GUESSING this is a bug, but of course it can't be changed forevermore because of backwards compatibility :(

这篇关于递归遍历 OnInit 中的控件禁用 GridView RowCommand 并丢失 Viewstate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆