Two UpdatePanels on a page…
Yep, I’m still in vacations…since I’ve been answering one or two posts in the ATLAS forums, I’ve though that I should document those little hacks that I mention there here. This might make life easy for the others. As you might remember, I’ve started writing about ATLAS. Though I still haven’t presented the UpdatePanel control (I know I’ll talk about it one day ), I think it’s a good idea to present a solution to a known problem: suppose you have two UpdatePanels on a page and a click on a button placed inside one of the panels should only refresh the second (note the only!). You can easily refresh the second panel by creating a trigger (ControlEventTrigger) on the button placed on the first panel. Well, this will refresh the second panel but the client will also get the HTML of the first panel since the button that started the partial postback is placed on the first panel.
To understand what’s going on, you must understand that during a partial postback, the ScriptManager handles the LoadPostData method in a special way: it tries to find the UpdatePanel “responsible” for the partial postback and marks it as requiring an update. Yes, this also happens to panels which are associated to a trigger. So, what we need is a way to “unmark” that panel as requiring an update. Unfortunately, the UpdatePanel only has a method that lets you force a refresh of its content. So, to solve this, you must use reflection and a non-documented approach. Here’s a demo page that shows what you must do in order to only get the HTML of the second panel:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void h(object sender, EventArgs args)
{
panel1.GetType().InvokeMember(
"_requiresUpdate",
System.Reflection.BindingFlags.Instance|System.Reflection.BindingFlags.NonPublic|
System.Reflection.BindingFlags.SetField,
null,
panel1,
new object[] { false });
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<atlas:scriptmanager runat="server" id="manager" enablepartialrendering="true" />
<atlas:UpdatePanel runat="server" id="panel1" Mode="Conditional">
<contenttemplate>
<asp:Button runat="server" ID="bt" Text="Submit" OnClick="h" />
<%=DateTime.Now.ToString() %>
</contenttemplate>
</atlas:UpdatePanel>
<hr />
<atlas:UpdatePanel runat="server" id="UpdatePanel1" Mode="Conditional">
<contenttemplate>
<%=DateTime.Now.ToString() %>
</contenttemplate>
<Triggers>
<atlas:ControlEventTrigger ControlID="bt" EventName="Click" />
</Triggers>
</atlas:UpdatePanel>
</form>
</body>
</html>
Basically, I'm using reflection to change the value of the private _requiresUpdate field of the panel and setting it to false. By doing this, we're saying that the panel doesn't require an udpate and due to this its contents aren't gonna be sent back to the client.