GridView中的LinkButton触发了全页回发,且此GridView被包含在UpdatePanel中。

38

我有一个GridView,里面放在了UpdatePanel里面。在一个模板字段中有一个用于标记项目的按钮。功能上来说是可以正常工作的,但该按钮总是触发全页面回发而不是部分回发。如何才能让该按钮触发部分回发?

<asp:ScriptManager ID="ContentScriptManager" runat="server" />
<asp:UpdatePanel ID="ContentUpdatePanel" runat="server" ChildrenAsTriggers="true">
    <ContentTemplate>
        <asp:GridView ID="OrderGrid" runat="server" AllowPaging="false" AllowSorting="false"
            AutoGenerateColumns="false">
            <Columns>
                <asp:TemplateField HeaderText="">
                    <ItemTemplate>
                        <asp:LinkButton ID="MarkAsCompleteButton" runat="server" Text="MarkAsComplete"
                            CommandName="MarkAsComplete" CommandArgument='<%# Eval("Id") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="Name" HeaderText="Name" />
                <asp:BoundField DataField="LoadDate" HeaderText="Load Date" />
                <asp:BoundField DataField="EmployeeCutOffDate" HeaderText="Cut Off Date" />
                <asp:BoundField DataField="IsComplete" HeaderText="Is Completed" />
            </Columns>
        </asp:GridView>
    </ContentTemplate>
</asp:UpdatePanel>

我在一个全新的项目上创建了这个场景。每次都只能实现部分的回传,而无法实现完整的回传。你还能想到其他什么奇怪的因素吗? - Paul Lemke
你能否发布一下你在“MarkAsComplete”命令上所做的代码? - Paul Lemke
请确保您没有在Firefox上使用Web开发工具禁用了所有JavaScript。 - Cem
8个回答

84

你需要将每个LinkButton注册为AsyncPostBackTrigger。在GridView的每一行绑定之后,您需要通过代码后台搜索LinkButton并进行注册,如下所示:

protected void OrderGrid_RowDataBound(object sender, GridViewRowEventArgs e)  
{  
   LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton;  
   ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb);  
}  

这还需要将 ClientIDMode="AutoID" 设置为LinkButton,如这里所提到的(感谢Răzvan Panda指出)。


1
@Lionel在下面提到了一些非常有用的东西,除了这个答案之外。在OrderGrid_RowDataBound处理程序内部,智能检查当前行是否为数据行是明智的(因为你要查找的“LinkButton”可能不在标题行上)。if (e.Row.RowType == DataControlRowType.DataRow) { LinkButton lb = e.Row.FindControl("MarkAsCompleteButton") as LinkButton; ScriptManager.GetCurrent(this).RegisterAsyncPostBackControl(lb); }否则,当您无法找到该按钮的ID时,您将获得NPE。 - bradykey
1
如果您的GridView不在UpdatePanel中,则此方法将无法正常工作。请改用RowCreated方法。 - gUIDo

6

可能不是建议的做法,但您可以通过在AsyncPostBackTrigger中排除EventName使GridView上的所有内容都可以异步工作,例如:

<Triggers>
  <asp:AsyncPostBackTrigger ControlID="OrderGrid" />
</Triggers>

这将使得GridView的RowCommand事件和其他事件以异步方式触发。请注意,当您在GridView上设置ClientIDMode="Static"时,它会导致完全的后台提交。


谢谢!ClientIDMode="Static"是问题所在!去掉它后,它又可以正常工作了。 - Adam
“当您在GridView上设置ClientIDMode="Static"时,会导致完整的后台提交”这个提示非常有帮助。由于其他原因我无法取消ClientIDMode="Static",但是这个提示和将每个LinkButton强制注册为异步后台提交控件一起解决了我的问题。非常感谢! - bradykey

5

我的网格视图处于条件模式。

protected void gvAgendamentoExclui_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow) {
            LinkButton lnk = e.Row.FindControl("LinkButton2") as LinkButton;
            AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
            trigger.ControlID = lnk.UniqueID;
            trigger.EventName = "Click";
            UpdatePanel2.Triggers.Add(trigger);

        }
    }

在linkbutton的点击事件中,我放置了以下代码:
protected void LinkButton2_Click(object sender, EventArgs e)
    {
        UpdatePanel2.Update();
    }

你的GridView处于条件模式是什么意思? - Jaimie Knox
这会产生错误 System.InvalidOperationException 异常:在 UpdatePanel 'UpdatePanel2' 的触发器中找不到 ID 为 'LinkButton2' 的控件。 - James Wierzba

1
请将以下元素放置在web.config文件的system.web元素内:
<xhtmlConformance mode="Transitional"/>

0

MSDN指定UpdatePanel.ChildrenAsTriggers属性“[获取或设置一个值,该值指示来自UpdatePanel控件的直接子控件的后台更新面板内容”(请参见http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.childrenastriggers.aspx)。

由于您的LinkButton似乎不是“直接子控件”,因此我建议将LinkButton配置为显式的AsyncPostBackTrigger。

在您的</ContentTemplate>标记下方,尝试添加以下内容:

<Triggers>
  <asp:AsyncPostBackTrigger ControlID="MarkAsCompleteButton" EventName="Click" />
</Triggers>

3
这不起作用,因为该控件ID在行外不可见。 - Kevin Albrecht

0

这可能有点老了,但我的解决方案是在itemTemplate内部放置一个update panel,并在gridview外部再放置一个。

触发器应该是gridview,而外部触发器应该是gridview和PageIndexChanging。试试看吧。


除了您的答案之外,您还应该确保包含您找到的代码,以帮助未来遇到相同问题的读者。 - buczek

0

我遇到了一个问题,其中一个表单(page1)运行良好,另一个表单(page2)则需要进行整个页面的后退操作。结果发现,当我制作第二个页面时,我做了太多的剪切/粘贴,并且在表单定义中仍然有一个javascript调用。

< form id="form1" runat="server" onsubmit="return checkstuff();">

但是在 page 2 中未定义 checkstuff

删除了 onsubmit,部分提交开始工作。

在工作页面 - page 1 中,checkstuff 被定义,但只是一个存根,仅返回 true。 为了好玩,我在 checkstuff 中加了一个警报,并且确实为所有提交(部分或不是部分)调用了它。 如果我将存根更改为只返回 false,则根本不会发生任何事情。

所有这些的要点是,JavaScript 仍然被执行,就像提交了完整的页面一样。 因此,请仔细检查您的客户端脚本。


-1
你需要为每个RowState注册每个控件。 1:为RowState = Alternate和Normal注册您的控件。 2:为RowState = Edit注册您的控件。 3:...
ASPX:
<asp:TemplateField HeaderText="">
                <ItemTemplate>
                    <asp:LinkButton runat="server" ID="Btn1" 
                        CommandName="Edit" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-pencil-square-o"></i></asp:LinkButton>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:LinkButton ID="Btn2" runat="server" CommandName="Update" CommandArgument='<%# Container.DataItemIndex + ";" + Eval("idinterlocuteur") %>'><i class="fa fa-check"></i></asp:LinkButton>
                </EditItemTemplate>
            </asp:TemplateField>

代码后端:

protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow 
        && (e.Row.RowState == DataControlRowState.Normal 
            || e.Row.RowState == DataControlRowState.Alternate))
    {
        LinkButton Btn1 = e.Row.FindControl("Btn1 ") as LinkButton; 
        ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn1 );
    }
    if (e.Row.RowType == DataControlRowType.DataRow 
        && e.Row.RowState == DataControlRowState.Edit)
    {
        LinkButton Btn2 = e.Row.FindControl("Btn2 ") as LinkButton;
        ScriptManager.GetCurrent(this.Parent.Page).RegisterAsyncPostBackControl(Btn2 );      
    }
}

欢迎来到Stack Overflow!提供额外的解释可以改善你的答案。 - ryanyuyu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接