Определите, какой 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
}
}
}
Любая помощь!
Ответы
Ответ 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