确定哪个UpdatePanel导致了部分(异步)PostBack?

13

如果一个页面包含两个UpdatePanels,如何知道是哪个UpdatePanel导致了局部的PostBack

我的意思是在Page_Load事件处理程序中。

这是我的代码:

 <asp:ScriptManager ID="ScriptManager1" runat="server">
 </asp:ScriptManager>
 <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" 
     onprerender="UpdatePanel1_PreRender">
     <ContentTemplate>
         <A:u1 ID="u1" runat="server" />
     </ContentTemplate>
 </asp:UpdatePanel>
 <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional" 
     onprerender="UpdatePanel2_PreRender">
     <ContentTemplate>
         <A:u2 ID="u2" runat="server" />
     </ContentTemplate>
 </asp:UpdatePanel>
我试了这段代码,但它几乎没起作用!
protected void Page_Load(object sender, EventArgs e)
{
    if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
    {
        if (UpdatePanel1.IsInPartialRendering)
        {
            // never enter to here
        }
        if (UpdatePanel2.IsInPartialRendering)
        {
            // neither here
        }
    }
}

有人能帮忙吗!

6个回答

11

您可以使用UpdatePanel类的IsInPartialRendering属性来确定特定面板是否导致部分回发:

protected void Page_Render(object sender, EventArgs e)
{
    if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) {
        if (yourFirstUpdatePanel.IsInPartialRendering) {
            // The first UpdatePanel caused the partial postback.
        } else if (yourSecondUpdatePanel.IsInPartialRendering) {
            // The second UpdatePanel caused the partial postback.
        }
    }
}

编辑:看起来在Render阶段之前,IsInPartialRendering始终为false。由于您希望在Load阶段获取该信息,因此它将无法按预期工作。请参见此错误

有一个解决方法在此处记录,它包括从UpdatePanel派生自己的类以访问其受保护的RequiresUpdate属性:

public class ExtendedUpdatePanel : UpdatePanel
{
    public bool IsUpdating
    {
        get {
            return RequiresUpdate;
        }
    }
}

在您的页面标记中将asp:UpdatePanel替换为ExtendedUpdatePanel后,上面的代码变为:
protected void Page_Load(object sender, EventArgs e)
{
    if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) {
        if (yourFirstUpdatePanel.IsUpdating) {
            // The first UpdatePanel caused the partial postback.
        } else if (yourSecondUpdatePanel.IsUpdating) {
            // The second UpdatePanel caused the partial postback.
        }
    }
}

@John,这是一个页面生命周期问题,请参考我的更新答案以找到解决方法。 - Frédéric Hamidi
@Frédéric:你如何替换asp:updatepanel标记?你必须创建并注册一个用户控件吗? - Andy F
1
这对我不起作用-无论我尝试过什么页面状态,IsUpdating始终为真。 - MisterZimbu
@MisterZimbu,也许你的所有“UpdatePanels”需要同时刷新(例如,它们的“UpdateMode”属性设置为“Always”而不是“Conditional”)? - Frédéric Hamidi
@Frederic:那可能就是了。我采用了AsyncPostbackSourceElementID方法(因为我真的在寻找触发更新的UpdatePanel)。 - MisterZimbu
显示剩余3条评论

7

试试这个:

ScriptManager.GetCurrent().AsyncPostBackSourceElementID

3
这解决了我的问题。我使用了一个像这样的if语句:if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack && ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID == control.UniqueID) - 你需要将其与UniqueID进行比较,而不是ClientID,如果您的更新面板包含多个控件,则需要测试每个控件。 - johna

5

如果您不想扩展原始的UpdatePanel类,您也可以使用以下解决方法:

string id = ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID;

因此,您可以检查生成的ID并添加一些条件子句来确定应执行哪些代码。该ID应等于通过javascript函数__doPostBack('someid','')传递的第一个参数。
例如,我在我的Update Panel中有一个用户控件:此控件包含一堆链接按钮,触发UpdatePanel。我还可以使用某些外部链接手动更新此面板(使用类似__doPostBack('myUpdatePanelClientId','')的内容。
也就是说,在我的情况下,我看到了三种不同的加载UpdatePanel的方法:
1.首次页面加载; 2.在我的UpdatePanel内单击链接按钮(或任何其他类型的按钮); 3.在UpdatePanel之外触发PostBack。
每种情况都会给我一个不同的ID。第一种情况给我一个空字符串(因为这是第一次页面加载,尚未触发任何使用__doPostBack函数的PostBack)。第二个给我推到用户控件中的按钮的唯一ID(这是最初和预期的ASP.NET行为)。第三种方法正好给我编码方法时传递的第一个参数(即UpdatePanel的ClientId)。
以下是我成功实现我的UpdatePanel用例的方式(假设我正在使用部分呈现模式)。这并不完美,但它按预期工作。
protected void myUpdatePanel_Load(object sender, EventArgs e)
{
    string id = ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID;

    bool firstLoad = (String.IsNullOrEmpty(id));
    bool triggerFromUpdatePanel = !firstLoad && (id.Contains(userControlInsideMyUpdatePanel.UniqueID));
    bool triggerFromExternalControl = !firstLoad && (id == myUpdatePanel.ClientID);

    // case 1, 2, 3.
    if ((firstLoad)  || (triggerFromUpdatePanel)  || (triggerFromExternalControl ))
    {
        // do something
    }
    else 
    {
        // do nothing!
    }


}

0
在客户端使用:
function EndRequestHandler(sender, args) { if (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.asyncTarget == '要进行回发的元素的ID') { // 做一些事情…… } } Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

0
如果设置了asyncpostbackelementid,那么你可以检查UpdatePanel的uniqueid是否以该id开头,这意味着它在里面,因为UpdatePanel是命名容器。

-1
可以确定更新面板内的对象并执行所需的代码。
If (ScriptManager.GetCurrent(Page).IsInAsyncPostBack) Then
                Dim id As String = ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID
                Dim Obj = UpdatePanel1.FindControlRecursive(id)
                If Not IsNothing(Obj) Then
                    a = 1
                End If
End If

以下是用于在更新面板中查找对象的函数。它是System.Web.UI.Control的扩展。

a=1是所需的代码。

 Public Module thisExtensions
        <System.Runtime.CompilerServices.Extension> _
        Public Function FindControlRecursive(control As System.Web.UI.Control, id As String) As System.Web.UI.Control
            If control Is Nothing Then
                Return Nothing
            End If
            'try to find the control at the current level
            Dim ctrl As Control = control.FindControl(id)

            If ctrl Is Nothing Then
                'search the children
                For Each child As Control In control.Controls
                    ctrl = FindControlRecursive(child, id)

                    If ctrl IsNot Nothing Then
                        Exit For
                    End If
                Next
            End If
            Return ctrl
        End Function
    End Module

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