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

时间:2011-01-31 13:59:19

标签: asp.net updatepanel postback

在一个页面中包含两个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 个答案:

答案 0 :(得分:11)

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

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

编辑:在IsInPartialRendering阶段之前,false似乎始终为Render。由于您希望在Load阶段期间获得该信息,因此无法按预期工作。请参阅this bug

解决方法documented here包括从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.
        }
    }
}

答案 1 :(得分:7)

试试这个:

ScriptManager.GetCurrent().AsyncPostBackSourceElementID

答案 2 :(得分:5)

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

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

因此,您可以检查结果id并添加一些条件子句以确定应执行哪些代码。此id应该等于通过javascript函数__doPostBack('someid', '')传递的第一个参数。

例如,我的更新面板中有一个用户控件:此控件包含一组触发UpdatePanel的链接按钮。)我也可以从一些外部链接手动更新此面板(使用类似__doPostBack('myUpdatePanelClientId', '');的内容

就我而言,我看到了加载UpdatePanel的三种不同方式:

  • 第一页加载;
  • 在我的UpdatePanel内点击了链接按钮(或任何其他类型的按钮);
  • 在UpdatePanel外触发PostBack。

每个场景都给了我不同的身份。第一个给我一个空字符串(因为这是第一个页面加载,还没有用__doPostBack函数触发任何回发。)

第二个给了我在用户控件中推送的按钮的UniqueId(这是原始和预期的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!
    }


}

答案 3 :(得分:0)

如果设置了asyncpostbackelementid,那么您可以检查updatepanel的uniqueid是否以该id开头,这意味着它位于其中,因为updatepanels正在为容器提供信息。

答案 4 :(得分:0)

在客户端使用:

function EndRequestHandler(sender,args){         if(Sys.WebForms.PageRequestManager.getInstance()._ postBackSettings.asyncTarget =='id of element do postback'){              // 做一点事 。 。 。         }     }     。Sys.WebForms.PageRequestManager.getInstance()add_endRequest(EndRequestHandler);

答案 5 :(得分:-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

在用于在更新面板中查找de object的函数下方。是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