Подтвердить что ты не робот

Определите, какой 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
        }
    }
}

Любая помощь!

4b9b3361

Ответ 1

Вы можете использовать свойство 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.
        }
    }
}

EDIT: Похоже, что IsInPartialRendering всегда false перед фазой Render. Поскольку вы хотите эту информацию во время фазы 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.
        }
    }
}

Ответ 2

Попробуйте следующее:

ScriptManager.GetCurrent().AsyncPostBackSourceElementID

Ответ 3

Если вы не хотите расширять исходный класс UpdatePanel, вы также можете использовать этот обходной путь:

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

Таким образом, вы можете проверить полученный идентификатор и добавить некоторые условные предложения, чтобы определить, какой код должен выполняться. Этот идентификатор должен быть равен первому параметру, который был передан через функцию javascript __doPostBack('someid', '').

Например, у меня есть элемент управления пользователя в моей панели обновления: этот элемент управления содержит пучок ссылок, которые запускают UpdatePanel.) Я также могу вручную обновить эту панель с некоторых внешних ссылок (используя что-то вроде __doPostBack('myUpdatePanelClientId', '');

То есть, в моем случае, я вижу три разных способа загрузки моей UpdatePanel:

  • Загрузка первой страницы;
  • Кнопка Link (или любой другой тип кнопки) щелкнула внутри моей UpdatePanel;
  • PostBack запускается вне UpdatePanel.

Каждый сценарий дает мне другой идентификатор. Первая из них дает мне пустую строку (так как это загрузка первой страницы, еще не было никакой обратной передачи с функцией __doPostBack.)

Вторая дает мне UniqueId кнопки, которая была нажата внутри пользовательского элемента управления (это исходное и ожидаемое поведение ASP.NET.)

Третий дает мне именно то, что я передал в качестве первого аргумента, когда я закодировал метод (то есть: ClientId из UpdatePanel.)

Вот как мне удалось реализовать мой вариант использования 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 начинается с этого идентификатора, то есть внутри него, поскольку пакеты обновлений находятся в контейнерах.

Ответ 5

На стороне клиента используйте:

функция EndRequestHandler (отправитель, args) {       if (Sys.WebForms.PageRequestManager.getInstance()._ postBackSettings.asyncTarget == 'Идентификатор элемента 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