Customizing the rendering of the UpdatePanel

Over the past few months I've received some feedback that there need to be more ways to customize the rendering of the UpdatePanel control. The response I gave was that we felt that using <div> and <span> would cover by far most scenarios. The one thing I would have loved to add to UpdatePanel is at least a CssClass property, but there are some workarounds to it, so we ended up not adding it.

To satisfy the demands of at least some of you, I've written a custom UpdatePanel that supports using arbitrary tags for the rendering as well as a new CssClass property.

namespace LeftSlipper {
    using System;
    using System.ComponentModel;
    using System.Web.UI;
    using Microsoft.Web.UI;

    public class CustomUpdatePanel : UpdatePanel {
        private string _cssClass;
        private HtmlTextWriterTag _tag = HtmlTextWriterTag.Div;

        [DefaultValue("")]
        [Description("Applies a CSS style to the panel.")]
        public string CssClass {
            get {
                return _cssClass ?? String.Empty;
            }
            set {
                _cssClass = value;
            }
        }

        // Hide the base class's RenderMode property since we don't use it
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new UpdatePanelRenderMode RenderMode {
            get {
                return base.RenderMode;
            }
            set {
                base.RenderMode = value;
            }
        }

        [DefaultValue(HtmlTextWriterTag.Div)]
        [Description("The tag to render for the panel.")]
        public HtmlTextWriterTag Tag {
            get {
                return _tag;
            }
            set {
                _tag = value;
            }
        }

        protected override void RenderChildren(HtmlTextWriter writer) {
            if (IsInPartialRendering) {
                // If the UpdatePanel is rendering in "partial" mode that means
                // it's the top-level UpdatePanel in this part of the page, so
                // it doesn't render its outer tag. We just delegate to the base
                // class to do all the work.
                base.RenderChildren(writer);
            }
            else {
                // If we're rendering in normal HTML mode we do all the new custom
                // rendering. We then go render our children, which is what the
                // normal control's behavior is.
                writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
                if (CssClass.Length > 0) {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
                }
                writer.RenderBeginTag(Tag);
                foreach (Control child in Controls) {
                    child.RenderControl(writer);
                }
                writer.RenderEndTag();
            }
        }
    }
}

Here's the markup I used in my page (along with a fancy CSS rule):

<%@ Register Namespace="LeftSlipper" TagPrefix="ls" %>
...
<ls:CustomUpdatePanel runat="server" ID="CustomUpdatePanel1"
   
CssClass="greenPanel" Tag="B">
    <ContentTemplate>
        <asp:Label ID="Label1" runat="server"></asp:Label>
        <asp:Button ID="Button1" runat="server" Text="Button" />
    </ContentTemplate>
</ls:CustomUpdatePanel>

ls:CustomUpdatePanel runat="server" ID="CustomUpdatePanel1"
   
CssClass="greenPanel" Tag="B">
    <ContentTemplate>
        <asp:Label ID="Label1" runat="server"></asp:Label>
        <asp:Button ID="Button1" runat="server" Text="Button" />
    </ContentTemplate>
</ls:CustomUpdatePanel>

And here's what got rendered with these settings (actual times may vary!):

<b id="CustomUpdatePanel1" class="greenPanel">
    <span id="Label1">12/6/2006 9:18:07 PM</span>
    <input type="submit" name="Button1" value="Button" id="Button1" />
</b>

As usual, feedback is welcome, or just enjoy the control!

Technorati Profile
Published Wednesday, December 06, 2006 9:17 PM by Eilon
Filed under: , , ,

Comments

# re: Customizing the rendering of the UpdatePanel

Thursday, December 07, 2006 4:43 AM by dth

Great ! thanks for this expected-though-not-requested component

# re: Customizing the rendering of the UpdatePanel

Thursday, December 07, 2006 8:59 AM by Edmund

Thanks!

I have a different unrelated question, though.

Why is the CssClass not backed up by a ViewState?

Edmund

# re: Customizing the rendering of the UpdatePanel

Thursday, December 07, 2006 1:12 PM by Eilon

Edmund,

There's no particular reason the CssClass property isn't stored in ViewState. It should be easy enough to modify the control to do that. However, one thing to consider is that if the UpdatePanel is the outer-most one being updated, it's outer HTML isn't updated.

Because of this, if the UpdatePanel "IsInPartialRendering" you'd have to output some script or use ScriptManager.RegisterDataItem() to send down the new CSS class to the client to be updated.

Perhaps I'll cover this in another blog post.

- Eilon

# re: Customizing the rendering of the UpdatePanel

Monday, December 18, 2006 4:49 PM by Vlad

How can I change the output stream in Page.Render() that has an UpdatePanel in an incremental refresh?

# re: Customizing the rendering of the UpdatePanel

Friday, February 02, 2007 1:07 PM by Mathlec

You did manage to modify the childs of the panel, but what if you were to change the OUTSIDE of the panel?

Like adding a header to the update panel in a div.

Overriding the Render method could be a good start?

# re: Customizing the rendering of the UpdatePanel

Wednesday, October 03, 2007 2:36 PM by Nick

Sorry for the stupid question. I'm at a new job coming from ColdFusion into ASP.Net. This looks like a very useful tag, but how do I create it? I tried creating a C# class containing this code, which built fine, but my .aspx file won't build because it can't see this object, even with the @Register command at the top.

# re: Customizing the rendering of the UpdatePanel

Wednesday, October 03, 2007 11:24 PM by Eilon

Nick:

What error are you getting? And where did you place the C# class? If you created a "Web Site" project the code file should be in the App_Code folder. If it's in a "Web Application" project you should be able to place the code file anywhere in the project.

Thanks,

Eilon

# re: Customizing the rendering of the UpdatePanel

Thursday, October 04, 2007 3:28 PM by Nick

"The type or namespace name 'Web' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)"

Some Googling suggests I should add a reference to System.Web.Extensions, but that has no effect.

# re: Customizing the rendering of the UpdatePanel

Thursday, October 04, 2007 3:33 PM by Eilon

Hi Nick,

As this sample was written before ASP.NET AJAX was released, it's using the old namespace. Everything that was Microsoft.* is now System.*. So, instead of "using Microsoft.Web.UI", you should do "using System.Web.UI" (which is already there anyway).

Thanks,

Eilon

# re: Customizing the rendering of the UpdatePanel

Friday, April 04, 2008 11:11 AM by Girish Singh

Nice, I certainly didn know that. Another tutorial i found online for the updatepanel was

www.mabaloo.com/.../Using-Update-Panel-In-Visual-web-Developer.html

<a href="www.mabaloo.com/.../Using-Update-Panel-In-Visual-web-Developer.html">www.mabaloo.com/.../Using-Update-Panel-In-Visual-web-Developer.html</a>

# re: Customizing the rendering of the UpdatePanel

Tuesday, September 09, 2008 8:06 AM by ReTox

This doesn't work. Try with more complex inner controls.

# re: Customizing the rendering of the UpdatePanel

Thursday, September 18, 2008 10:17 AM by Itamar

Works like a charm, thanks!

Leave a Comment

(required) 
(required) 
(optional)
(required)