代码之家  ›  专栏  ›  技术社区  ›  Hady

嵌套GridView不触发行事件

  •  0
  • Hady  · 技术社区  · 16 年前

    我有一个嵌套的GridView,它放在ListView中。GridView对绑定在其数据源中的所有实体进行完美的渲染。

    “我的gridview”中的每条记录都有两个按钮-“删除”和“编辑”。我遇到的问题是,连接到每个按钮的方法永远不会被触发。

    下面是我的代码[简化]的样子:

    <asp:ListView ID="uiListView" ... runat="server">
        <LayoutTemplate>
            ...
        </LayoutTemplate>
        <ItemTemplate>
            ...
            <asp:GridView ID="uiGridView"  
                        OnRowDataBound="uiGridView_RowDataBound"
                        OnRowEditing="uiGridView_RowEditing"
                        OnRowDeleting="uiGridView_RowDeleting" runat="server">
                <Columns>
                    ...
                    <asp:TemplateField>
                        <ItemTemplate>
                            <asp:Button ID="uiEditRowButton" CausesValidation="false" CommandName="Edit" Text="Edit" runat="server" />
                            <asp:Button ID="uiRemoveRowButton" CausesValidation="false" CommandName="Delete" Text="Remove" runat="server" />
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
            ...
        </ItemTemplate>
    </asp:ListView>
    

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack) {
            uiListView.ItemDataBound += new EventHandler<ListViewItemEventArgs>(uiListView_ItemDataBound);
            uiListView.DataSource = ...;
            uiListView.DataBind();
        }
    }
    
    // Find a GridView and bind relevant data to it
    private void uiListView_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
        if (e.Item.ItemType == ListViewItemType.DataItem) {
            ListViewDataItem listViewDataItem = (ListViewDataItem) e.Item;
    
            GridView uiGridView = (GridView)listViewDataItem.FindControl("uiGridView");
            ...
            uiGridView.DataSource = ...;
            uiGridView.DataBind();
        }
    }
    
    // For every row being bound to GridView, register the edit and delete
    // buttons as postback controls
    protected void uiGridView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            Control uiEditButton = e.Row.FindControl("uiEditRowButton");
            if (uiEditButton != null) {
                ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(uiEditButton);
            }
    
            Control uiRemoveRowButton = e.Row.FindControl("uiRemoveRowButton");
            if (uiRemoveRowButton != null) {
                ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(uiRemoveRowButton);
            }
        }
    }
    
    // Method runs when a GridView's edit button is clicked
    protected void uiGridView_RowEditing(object sender, GridViewEditEventArgs e)
    {
        Console.WriteLine('Editing Row...');
    }
    
    // Method runs when a GridView's delete button is clicked
    protected void uiGridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        Console.WriteLine('Deleting Row');
    }
    

    我试图修改上面的代码并删除“!IsPostBack”子句,事件实际上是在单击GridView中的按钮时触发的。但是,我觉得在每次回发时都进行数据绑定并不舒服,我认为应该有比这更好的解决方案。

    2 回复  |  直到 16 年前
        1
  •  2
  •   Corey Carter    15 年前

    我知道这个职位是旧的,但偶然发现我的项目工作很晚。我不是专家,但我相信问题在于将ItemDataBound事件设置在!回发。Databind()可以保留在Postback语句中,但设置事件需要在外部。回发时,ItemDataBound事件不再存在,因此gridview事件不存在,因为它包含在listview的ItemDataBound事件中。所以呢

    if (!IsPostBack) {
        uiListView.ItemDataBound += new EventHandler<ListViewItemEventArgs>(uiListView_ItemDataBound);
        uiListView.DataSource = ...;
        uiListView.DataBind();
    }
    

    应该是。。。。

    uiListView.ItemDataBound += new EventHandler<ListViewItemEventArgs>(uiListView_ItemDataBound);
    
    if (!IsPostBack) {        
        uiListView.DataSource = ...;
        uiListView.DataBind();
    }
    

    在代码隐藏的控件上设置事件时,通常最好总是在Posback语句之外设置它们。当在aspx页面上设置它们时,这并不重要,因为它将始终存在。

        2
  •  1
  •   Community Mohan Dere    6 年前

    事件处理程序,而不是RowCommand事件处理程序。

    GridView.OnRowCreated方法:

    可以呈现GridView控件, 控件中的每一行。这个 GridView控件中的行无效 创建。这使您能够提供 自定义例程,如添加 事件发生。

    GridView.OnRowDataBound方法:

    在呈现GridView控件之前, 到数据源中的记录。这个 数据行(由GridViewRow表示) 对象)绑定到 GridView控件。这使您能够 提供一个事件处理方法 修改数据绑定的值 发生。

    现在,msdn报告中不清楚的是:

    1. 从数据源-调用DataBind时传递的
    2. 在回发时,从ViewState而不是从数据源加载行

    因此,当发生回发时,我们需要在每一行上再次绑定按钮事件。但是,因为我们在row命令中连接事件,所以这些方法永远不会被再次调用,因为它们只在DataBind上被激发。我们需要做的是连接RowCreated方法中的按钮,当我们第一次将数据绑定到GridView时,将调用该方法;当从GridView的ViewState创建行时,将在每次回发时调用该方法。