Determine which UpdatePanel causes the partial (asynchronous) PostBack?

前端 未结 6 1270
花落未央
花落未央 2020-12-05 19:55

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

I mean in the Page_L

相关标签:
6条回答
  • 2020-12-05 20:27

    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!
        }
    
    
    }
    
    0 讨论(0)
  • 2020-12-05 20:31

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

    0 讨论(0)
  • 2020-12-05 20:38

    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.
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-05 20:48

    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
    
    0 讨论(0)
  • 2020-12-05 20:49

    Try this:

    ScriptManager.GetCurrent().AsyncPostBackSourceElementID
    
    0 讨论(0)
  • 2020-12-05 20:49

    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.

    0 讨论(0)
提交回复
热议问题