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&开发者_如何学Cgt;
<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!
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.
}
}
}
Try this:
ScriptManager.GetCurrent().AsyncPostBackSourceElementID
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!
}
}
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.
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);
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
精彩评论