Определить, какая UpdatePanel вызывает частичный (асинхронный) PostBack? - PullRequest
13 голосов
/ 31 января 2011

На странице содержится два 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 ]

11 голосов
/ 31 января 2011

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

Здесь задокументировано обходное решение , которое заключается в извлечении вашего собственного класса из 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.
        }
    }
}
7 голосов
/ 31 января 2011

Попробуйте это:

ScriptManager.GetCurrent().AsyncPostBackSourceElementID
5 голосов
/ 02 июня 2011

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

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

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

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

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

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

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

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


}
0 голосов
/ 28 сентября 2015

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

function EndRequestHandler (sender, args) {if (Sys.WebForms.PageRequestManager.getInstance () ._ postBackSettings.asyncTarget == 'Id элемента do postback') {//сделай что-нибудь .,,}} Sys.WebForms.PageRequestManager.getInstance (). Add_endRequest (EndRequestHandler);

0 голосов
/ 03 июля 2015

возможно определить объект внутри панели обновления выполнить код, необходимый

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
0 голосов
/ 28 сентября 2012

Если установлено значение asyncpostbackelementid, вы можете проверить, что uniqueid панели обновления начинается с этого идентификатора, то есть он находится внутри него, поскольку панели обновления являются внутренними контейнерами.

...