how to get which UpdatePanel has posted

Last post 04-05-2007 1:27 PM by richardsoeteman.net. 14 replies.

Sort Posts:

  • how to get which UpdatePanel has posted

    12-20-2006, 7:15 AM
    • Member
      19 point Member
    • Bort
    • Member since 11-17-2006, 4:42 AM
    • Posts 51

    With partial page updates it becomes more feasible to create pages with no viewstate, however this requires a bit trickier coding. I have a DropDownList control that I need to rebind every time I am refreshing the UpdatePanel that contains it. The first thought is to put the binding process in the event handler of the item that caused the partial postback. However, since this occurs in the pipeline after the DropDown's selected value is applied, the selected value is lost. Thus the binding of the DropDown has to happen in the Page_Init stage. But at this stage I don't have the event yet unless you examine the raw posted data (ugly). It would be nice if the ScriptManager could be interogated on post back to tell us which UpdatePanel caused the partial post. Then in the Page_Init I can say "If the UpdatePanel doing the posting contains my DropDown then do the binding". I have not seen any way to get a reference of the UpdatePanel that contains the control that triggered the partial post back. If it exists I would like to know.

    Thanks

  • Re: how to get which UpdatePanel has posted

    12-20-2006, 10:17 AM
    • Member
      63 point Member
    • bogdanb
    • Member since 07-30-2006, 7:12 AM
    • Posts 29

    Instead of interogating the ScriptManager we can interogate each UpdatePanel's IsInPartialRendering property to know if an update panel is part of the asynchronous postback. Maybe you can figure a way around this property instead.

     

    Bogdan 

  • Re: how to get which UpdatePanel has posted

    12-20-2006, 4:59 PM
    • Member
      19 point Member
    • Bort
    • Member since 11-17-2006, 4:42 AM
    • Posts 51
    Is there a way to find out which control triggered the partial postback within the updatepanel?
  • Re: how to get which UpdatePanel has posted

    12-20-2006, 5:08 PM
    • Member
      19 point Member
    • Bort
    • Member since 11-17-2006, 4:42 AM
    • Posts 51
    BTW, I always get a False value on the IsInPartialRendering property of all my UpdatePanels so this property seems useless.
  • Re: how to get which UpdatePanel has posted

    12-20-2006, 5:09 PM
    • Contributor
      2,460 point Contributor
    • Steve Marx
    • Member since 05-26-2006, 8:35 PM
    • Microsoft
    • Posts 643
    You can use:

    ScriptManager

    .GetCurrent(Page).AsyncPostBackSourceElementID

    to see what caused the async postback.

    Steve Marx | ASP.NET AJAX Evangelist | Microsoft Corporation
  • Re: how to get which UpdatePanel has posted

    12-20-2006, 7:31 PM
    • Contributor
      6,253 point Contributor
    • CyrilCS
    • Member since 08-16-2006, 9:48 PM
    • DURAND
    • Posts 21

    Hi,

    I think this code would help you.

       86         private static UpdatePanel FindRefreshedUpdatePanelRecursive(Control parent, ScriptManager sc)

       87         {

       88             foreach (Control child in parent.Controls)

       89             {

       90                 if (child is UpdatePanel)

       91                 {

       92                     foreach (UpdatePanelTrigger trigger in ((UpdatePanel)child).Triggers)

       93                     {

       94                         String ControlID;

       95                         if (trigger is AsyncPostBackTrigger)

       96                             ControlID = ((AsyncPostBackTrigger)trigger).ControlID;

       97                         else if (trigger is PostBackTrigger)

       98                             ControlID = ((PostBackTrigger)trigger).ControlID;

       99                         else

      100                             continue;

      101 

      102                         if (child.NamingContainer.FindControl(ControlID).UniqueID == sc.AsyncPostBackSourceElementID)

      103                             return (UpdatePanel)child;

      104                     }

      105                 }

      106                 UpdatePanel c = FindRefreshedUpdatePanelRecursive(child, sc);

      107                 if (c != null)

      108                 {

      109                     return c;

      110                 }

      111             }

      112             return null;

      113         }

     

  • Re: how to get which UpdatePanel has posted

    12-22-2006, 12:43 PM
    • Member
      73 point Member
    • ericpopivker
    • Member since 04-21-2006, 8:06 PM
    • New York, NY
    • Posts 21

    Thanks for the code, Cyril...

    There is one more case.  UpdatePanel can be refreshed using a submit button or another control inside it.  In that case you would need to use code like this:

                Control control=this.Page.FindControl(scriptManager.AsyncPostBackSourceElementID);

                while (control != null)
                {
                    if (control is UpdatePanel)
                          return (UpdatePanel)control;

                     control = control.Parent;
                }

                return null;

    Regards,

    Eric

     

    DeveloperX
  • Re: how to get which UpdatePanel has posted

    12-22-2006, 3:04 PM
    • Member
      21 point Member
    • ewlloyd
    • Member since 01-23-2006, 6:24 AM
    • Posts 6

    Gents, 

    Actually, it gets worse. Both code blocks above make the assumption that the triggering AsyncPostBackSourceElementID is a child of the UpdatePanel in question. This is by no means a safe assumption.

    External triggers could set it off. The only way I can see to ensure that you've unequivocally determined which UpdatePanel is being processed is to iterate the UpdatePanels (for which there is no simple method), iterate their triggers (which have to be cast either to PostBackTrigger or AsyncPostBackTrigger to get the ControlID), and compare said ControlIDs with the AsyncPostBackSourceElementID. If you try to generalize it across all the UpdatePanels on a page, it gets pretty Rube Goldberg. I'm using the following code to tell if a specific panel is being updated:

    	private bool IsUpdating(ScriptManager sm, UpdatePanel up) {
    		string elemID = sm.AsyncPostBackSourceElementID;
    		foreach (UpdatePanelTrigger t in up.Triggers) {
    			PostBackTrigger pt = t as PostBackTrigger;
    			if (pt != null)
    				if (pt.ControlID == elemID)
    					return true;
    			AsyncPostBackTrigger apt = t as AsyncPostBackTrigger;
    			if (apt != null)
    				if (apt.ControlID == elemID)
    					return true;
    		}
    		return false;
    	}
    
    
     

    Why the UpdatePanel doesn't provide an event to indicate that it's getting partially updated is quite beyond me. This seems like a glaring hole in the implementation. If there was a compelling reason to leave this out, I'd be very curious to hear it.

    Cheers!

    Eric

  • Re: how to get which UpdatePanel has posted

    12-22-2006, 3:14 PM
    • Member
      21 point Member
    • ewlloyd
    • Member since 01-23-2006, 6:24 AM
    • Posts 6

    My apologies, Cyril.

    I didn't get a really good look at your code before posting. You do seem to have the problem covered pretty well. One thing neither of us handles quite right is the case where a single control might trigger the update of multiple panels.

    Still, does anyone else find it just a bit crazy that we have to go to this monumental effort just to determine which panels are being updated? There should be a better way.

    Cheers!

    Eric

  • Re: how to get which UpdatePanel has posted

    12-22-2006, 3:25 PM
    • Member
      73 point Member
    • ericpopivker
    • Member since 04-21-2006, 8:06 PM
    • New York, NY
    • Posts 21

    Hi Eric,

    The better way would be if UpdatePanel.IsInPartialRendering would actually return the correct value.  Unfortunately it doesn't work correctly and always seems to return false.

    Right now Cyril's and my code only returns the first UpdatePanel, but it should be pretty easy to modify our code to return a list of all panels being refreshed.

    Regards,

    Eric P
     


     

    DeveloperX
  • Re: how to get which UpdatePanel has posted

    12-22-2006, 5:53 PM
    • Contributor
      6,253 point Contributor
    • CyrilCS
    • Member since 08-16-2006, 9:48 PM
    • DURAND
    • Posts 21

    Hi,

    you're right, my code works only for refreshed panel fired with a trigger. This code would work in many case :

       96         public static UpdatePanel FindRefreshedUpdatePanel(ScriptManager sc)

       97         {

       98             Control control = sc.Page.FindControl(sc.AsyncPostBackSourceElementID);

       99             while (control != null)

      100             {

      101                 if (control is UpdatePanel)

      102                     return (UpdatePanel)control;

      103 

      104                 control = control.NamingContainer;

      105             }

      106 

      107             return FindRefreshedUpdatePanelRecursive(control.Page, sc);

      108         }

      109 

      110         private static UpdatePanel FindRefreshedUpdatePanelRecursive(Control parent, ScriptManager sc)

      111         {

      112 

      113             foreach (Control child in parent.Controls)

      114             {

      115                 if (child is UpdatePanel)

      116                 {

      117                     foreach (UpdatePanelTrigger trigger in ((UpdatePanel)child).Triggers)

      118                     {

      119                         String ControlID;

      120                         if (trigger is AsyncPostBackTrigger)

      121                             ControlID = ((AsyncPostBackTrigger)trigger).ControlID;

      122                         else if (trigger is PostBackTrigger)

      123                             ControlID = ((PostBackTrigger)trigger).ControlID;

      124                         else

      125                             continue;

      126 

      127                         if (child.NamingContainer.FindControl(ControlID).UniqueID == sc.AsyncPostBackSourceElementID)

      128                             return (UpdatePanel)child;

      129                     }

      130                 }

      131                 UpdatePanel c = FindRefreshedUpdatePanelRecursive(child, sc);

      132                 if (c != null)

      133                 {

      134                     return c;

      135                 }

      136             }

      137             return null;

      138         }

    But I think in some complex case it would not works. For example if we use UserControl, nested UpdatePanel and things like that ... I will have a look at this tommorow.

     

    ewlloyd > I don't try your code but it will not work, if (apt.ControlID == elemID) apt.ControlID is only the ID of the client and elemID is the UniqueID ... so if you use UserControl or MasterPage it will not work because the ControlID is different to UniqueID :-)

  • Re: how to get which UpdatePanel has posted

    12-26-2006, 3:47 PM
    • Member
      21 point Member
    • ewlloyd
    • Member since 01-23-2006, 6:24 AM
    • Posts 6

    Cyril, 

    Yeah, you're right. Good catch. I'll tweak on it some more as the need arises.

    Thanks!

    Eric

  • Re: how to get which UpdatePanel has posted

    04-04-2007, 4:31 PM

    Hi All,

    I faced the same problem this week. In the documentation I read about the RequiresUpdate property wich is a protected property on the UpdatePanel. Since it's a protected property I could'nt access it directly. That's why I created my own contol wich extends the update panel. I created an extra property "IsUpating", wich will indicate if an updatepanel is triggered for updating. The property will return true if a AscyncPostbackTrigger was raised or the Update method was called Directly. The downside of this solution is that the property is available not earlier then the OnLoadComplete Event.

    Here´s the code for the extended component

    1    using System;
    2    using System.Collections.Generic;
    3    using System.Text;
    4    using System.Web;
    5    using System.Web.UI;
    6    
    7    namespace UpdatePanelControlExtender
    8    {
    9        /// <summary>
    10       /// Extends the Normal UpdatePanel so we can determine if the 
    11       /// UpdatePanel is in PartialRendering stage.
    12       /// </summary>
    13       public class ExtendedUpdatePanel : UpdatePanel
    14       {
    15   
    16           /// <summary>
    17           /// Indicates that the UpdatePanel is updating
    18           /// </summary>
    19           public bool IsUpdating
    20           {
    21               get
    22               {
    23                   return this.RequiresUpdate;
    24               }
    25           }
    26       }
    27   
    28   }
    29   
    Below you find the Sample ASPX and the Code behind I used for testing. Basicly you have three buttons:
    1. UpdateButton. The click event is added to the AsyncPostbackTriggerCollection, so ExtendedUpdatePanel2 will be updated
    2.  UpdateInCodeBehind. The Click event handler calls the UodateMethod of ExtendedUpdatePanel2, so ExtendedUpdatePanel2  will be updated
    3.  NoUpdateButton. This button will cause an update ExtendedUpdatePanel2
     I have used an extra ExtendedUpdatepanel (ExtendedUpdatePanel1) to show is ExtendedUpdatePanel2 was updated.
     Default.aspx file
    1    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
    2    
    3    <%@ Register Assembly="UpdatePanelControlExtender" Namespace="UpdatePanelControlExtender"
    4        TagPrefix="cc1" %>
    5    
    6    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    7    <html xmlns="http://www.w3.org/1999/xhtml">
    8    <head runat="server">
    9        <title>Untitled Page</title>
    10   </head>
    11   <body>
    12       <form id="form1" runat="server">
    13           <asp:ScriptManager ID="ScriptManager1" runat="server" />
    14           <div>
    15               <cc1:extendedupdatepanel id="ExtendedUpdatePanel1" runat="server" UpdateMode="Conditional"><ContentTemplate>
    16   <asp:Label id="IsUpdatingLabel" runat="server" Text=""></asp:Label>
    17   </ContentTemplate>
    18                   <Triggers>
    19                       <asp:AsyncPostBackTrigger ControlID="NoUpdateButton" EventName="Click" />
    20                       <asp:AsyncPostBackTrigger ControlID="UpdateButton" EventName="Click" />
    21                       <asp:AsyncPostBackTrigger ControlID="UpdateInCodeBehind" EventName="Click" />
    22                   </Triggers>
    23   </cc1:extendedupdatepanel>
    24           </div>
    25           <cc1:extendedupdatepanel id="ExtendedUpdatePanel2" runat="server" UpdateMode="Conditional"><ContentTemplate>
    26   <asp:Label id="TriggerUpdateTimeLabel" runat="server" Text=""></asp:Label>
    27   </ContentTemplate>
    28               <Triggers>
    29                   <asp:AsyncPostBackTrigger ControlID="UpdateButton" EventName="Click">
    30                   </asp:AsyncPostBackTrigger>
    31               </Triggers>
    32   </cc1:extendedupdatepanel>
    33           <asp:Button ID="UpdateButton" runat="server" Text="Trigger Update Panel" />
    34           <asp:Button ID="UpdateInCodeBehind" runat="server" Text="Call Update statement in Click event"  OnClick="UpdateInCodeBehind_Click"/>
    35           <asp:Button ID="NoUpdateButton" runat="server" Text="Do not trigger" />
    36       </form>
    37   </body>
    38   </html>
    39   
    
     
    Code Behind
     
    1    using System;
    2    using System.Collections.Generic;
    3    using System.Text;
    4    using System.Web;
    5    using System.Web.UI;
    6    
    7    namespace UpdatePanelControlExtender
    8    {
    9        /// <summary>
    10       /// Extends the Normal UpdatePanel so we can determine if the 
    11       /// UpdatePanel is in PartialRendering stage.
    12       /// </summary>
    13       public class ExtendedUpdatePanel : UpdatePanel
    14       {
    15   
    16           /// <summary>
    17           /// Indicates that the UpdatePanel is updating
    18           /// </summary>
    19           public bool IsUpdating
    20           {
    21               get
    22               {
    23                   return this.RequiresUpdate;
    24               }
    25           }
    26       }
    27   
    28   }
    29   
    
     
    Richard
    http://www.richardsoeteman.net
  • Re: how to get which UpdatePanel has posted

    04-05-2007, 2:26 AM
    I posted the wrong code behind. Sorry for that. I will update it tonight.
    Richard
    http://www.richardsoeteman.net
  • Re: how to get which UpdatePanel has posted

    04-05-2007, 1:27 PM

    Hi All,

    Hereby the updated post. 

    I faced the same problem this week. In the documentation I read about the RequiresUpdate property wich is a protected property on the UpdatePanel. Since it's a protected property I could'nt access it directly. That's why I created my own contol wich extends the update panel. I created an extra property "IsUpating", wich will indicate if an updatepanel is triggered for updating. The property will return true if a AscyncPostbackTrigger was raised or the Update method was called Directly. The downside of this solution is that the property is available not earlier then the OnLoadComplete Event.

    Here´s the code for the extended component

    1    using System;
    2    using System.Collections.Generic;
    3    using System.Text;
    4    using System.Web;
    5    using System.Web.UI;
    6    
    7    namespace UpdatePanelControlExtender
    8    {
    9        /// <summary>
    10       /// Extends the Normal UpdatePanel so we can determine if the 
    11       /// UpdatePanel is in PartialRendering stage.
    12       /// </summary>
    13       public class ExtendedUpdatePanel : UpdatePanel
    14       {
    15   
    16           /// <summary>
    17           /// Indicates that the UpdatePanel is updating
    18           /// </summary>
    19           public bool IsUpdating
    20           {
    21               get
    22               {
    23                   return this.RequiresUpdate;
    24               }
    25           }
    26       }
    27   
    28   }
    29   
    Below you find the Sample ASPX and the Code behind I used for testing. Basicly you have three buttons:
    1. UpdateButton. The click event is added to the AsyncPostbackTriggerCollection, so ExtendedUpdatePanel2 will be updated
    2.  UpdateInCodeBehind. The Click event handler calls the UodateMethod of ExtendedUpdatePanel2, so ExtendedUpdatePanel2  will be updated
    3.  NoUpdateButton. This button will cause an update ExtendedUpdatePanel2
     I have used an extra ExtendedUpdatepanel (ExtendedUpdatePanel1) to show is ExtendedUpdatePanel2 was updated.
     Default.aspx file
    1    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
    2    
    3    <%@ Register Assembly="UpdatePanelControlExtender" Namespace="UpdatePanelControlExtender"
    4        TagPrefix="cc1" %>
    5    
    6    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    7    <html xmlns="http://www.w3.org/1999/xhtml">
    8    <head runat="server">
    9        <title>Untitled Page</title>
    10   </head>
    11   <body>
    12       <form id="form1" runat="server">
    13           <asp:ScriptManager ID="ScriptManager1" runat="server" />
    14           <div>
    15               <cc1:extendedupdatepanel id="ExtendedUpdatePanel1" runat="server" UpdateMode="Conditional"><ContentTemplate>
    16   <asp:Label id="IsUpdatingLabel" runat="server" Text=""></asp:Label>
    17   </ContentTemplate>
    18                   <Triggers>
    19                       <asp:AsyncPostBackTrigger ControlID="NoUpdateButton" EventName="Click" />
    20                       <asp:AsyncPostBackTrigger ControlID="UpdateButton" EventName="Click" />
    21                       <asp:AsyncPostBackTrigger ControlID="UpdateInCodeBehind" EventName="Click" />
    22                   </Triggers>
    23   </cc1:extendedupdatepanel>
    24           </div>
    25           <cc1:extendedupdatepanel id="ExtendedUpdatePanel2" runat="server" UpdateMode="Conditional"><ContentTemplate>
    26   <asp:Label id="TriggerUpdateTimeLabel" runat="server" Text=""></asp:Label>
    27   </ContentTemplate>
    28               <Triggers>
    29                   <asp:AsyncPostBackTrigger ControlID="UpdateButton" EventName="Click">
    30                   </asp:AsyncPostBackTrigger>
    31               </Triggers>
    32   </cc1:extendedupdatepanel>
    33           <asp:Button ID="UpdateButton" runat="server" Text="Trigger Update Panel" />
    34           <asp:Button ID="UpdateInCodeBehind" runat="server" Text="Call Update statement in Click event"  OnClick="UpdateInCodeBehind_Click"/>
    35           <asp:Button ID="NoUpdateButton" runat="server" Text="Do not trigger" />
    36       </form>
    37   </body>
    38   </html>
    39   
    
     
    Code Behind
     
    1    using System;
    2    using System.Data;
    3    using System.Configuration;
    4    using System.Web;
    5    using System.Web.Security;
    6    using System.Web.UI;
    7    using System.Web.UI.WebControls;
    8    using System.Web.UI.WebControls.WebParts;
    9    using System.Web.UI.HtmlControls;
    10   
    11   public partial class _Default : System.Web.UI.Page 
    12   {
    13       protected void Page_Load(object sender, EventArgs e)
    14       {
    15           //this.TriggerUpdateTimeLabel.Text = DateTime.Now.ToLongTimeString();
    16       }
    17   
    18       protected override void OnLoadComplete(EventArgs e)
    19       {
    20           base.OnLoadComplete(e);
    21           this.IsUpdatingLabel.Text = string.Format("Updatepanel updating = {0}", this.ExtendedUpdatePanel2.IsUpdating);
    22   
    23           if (this.ExtendedUpdatePanel2.IsUpdating)
    24           {
    25               this.TriggerUpdateTimeLabel.Text = string.Format("update triggered at{0}",DateTime.Now.ToLongTimeString());
    26           }
    27       }
    28   
    29       protected void UpdateInCodeBehind_Click(object sender, EventArgs e)
    30       {
    31           this.ExtendedUpdatePanel2.Update();
    32       }
    33   }
    
     
    Richard
    http://www.richardsoeteman.net
Page 1 of 1 (15 items)