Determine which UpdatePanel causes the partial (asynchronous) PostBack?

In a page contains two UpdatePanels, How can I know which UpdatePanel causes the partial PostBack ?

I mean in the Page_Load event handler.

This is my code:

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

I tried this code, but it isn’t worked alost!

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

Any help!

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

You can use the IsInPartialRendering property of the UpdatePanel class to determine if a specific panel caused the partial postback:

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

EDIT: It appears that IsInPartialRendering is always false before the Render phase. Since you want that information during the Load phase, it won’t work as expected. See this bug.

There’s a workaround documented here that consists in deriving your own class from UpdatePanel to access its protected RequiresUpdate property:

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

After replacing asp:UpdatePanel with ExtendedUpdatePanel in your page markup, the code above becomes:

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

Solution 2

Try this:

ScriptManager.GetCurrent().AsyncPostBackSourceElementID

Solution 3

If you don’t want to extend the original UpdatePanel class, you can also use this workaround:

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

Thus, you can examine the resulting id and add some conditional clauses to determine which code should execute. This id should be equal to the first parameter that was passed through the javascript function __doPostBack('someid', '').

For example, I have a user control in my Update Panel: this control contains a bunch of link buttons that trigger the UpdatePanel.) I also can manually update this panel from some external links (using something like __doPostBack('myUpdatePanelClientId', '');

That is, in my case, I see three different ways for loading my UpdatePanel:

  • First page load;
  • Link button (or any other type of button) clicked inside my UpdatePanel;
  • PostBack triggered outside the UpdatePanel.

Every scenario gives me a different id. The first one gives me an empty string (since this is the first page load, there hasn’t been yet any postback triggered with the __doPostBack function.)

The second one gives me the UniqueId of the button that was pushed inside the user control (this is the original and expected ASP.NET behavior.)

The third one gives me exactly what I passed as the first argument when I coded the method (ie: the ClientId of the UpdatePanel.)

Here’s how I succeeded to implement my UpdatePanel use case (assuming I’m using the partial rendering mode.) This is not perfect but it works as intended.

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


}

Solution 4

If the asyncpostbackelementid is set then you could check that updatepanel’s uniqueid starts with that id, meaning that is inside it since updatepanels are inaming containers.

Solution 5

In client side use:

function EndRequestHandler(sender, args) {
if (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.asyncTarget == ‘Id of element do postback’) {
// do something . . .
}
}
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

Solution 6

is possible to determine the object inside an update panel
an execute the code needed

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

below the function used to find de object inside the update panel. Is an extension of System.Web.UI.Control

a=1 Is the desired code.

 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

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply