【问题标题】:Determine which UpdatePanel causes the partial (asynchronous) PostBack?确定哪个 UpdatePanel 导致部分(异步)回发?
【发布时间】:2011-01-31 13:59:18
【问题描述】:

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

任何帮助!

【问题讨论】:

    标签: asp.net updatepanel postback


    【解决方案1】:

    您可以使用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.
            }
        }
    }
    

    编辑:看来IsInPartialRenderingRender 阶段之前总是false。由于您在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.
            }
        }
    }
    

    【讨论】:

    • @John,您观察到的行为是什么?您收到错误消息了吗?
    • 否,但如果语句从不输入,则不输入。
    • @John,这是一个页面生命周期问题,请参阅我更新的答案以了解解决方法。
    • @Frédéric:如何替换 asp:updatepanel 标记?是否必须创建和注册用户控件?
    • 这对我不起作用 - 无论我尝试过何种页面状态,IsUpdating 对我来说始终是正确的。
    【解决方案2】:

    试试这个:

    ScriptManager.GetCurrent().AsyncPostBackSourceElementID
    

    【讨论】:

    • 这解决了我的问题。我使用了这样的 if 语句: if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack && ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID == control.UniqueID) - 您需要比较 UniqueID 而不是 ClientID 并且您的更新面板是否包含更多不止一个控件,您需要对它们中的每一个进行测试。
    【解决方案3】:

    如果你不想扩展原来的 UpdatePanel 类,你也可以使用这个变通方法:

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

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

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

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

    • 首页加载;
    • 在我的 UpdatePanel 中单击了链接按钮(或任何其他类型的按钮);
    • 在 UpdatePanel 外部触发 PostBack。

    每个场景都会给我一个不同的 id。第一个给了我一个空字符串(因为这是第一个页面加载,还没有使用 __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!
        }
    
    
    }
    

    【讨论】:

      【解决方案4】:

      如果设置了 asyncpostbackelementid,那么您可以检查 updatepanel 的 uniqueid 是否以该 id 开头,这意味着它在其中,因为 updatepanel 是命名容器。

      【讨论】:

        【解决方案5】:

        在客户端使用:

        函数 EndRequestHandler(sender, args) { if (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.asyncTarget == 'Id of element do postback') { // 做一点事 。 . . } } Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

        【讨论】:

          【解决方案6】:

          可以确定更新面板内的对象 执行所需的代码

          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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多