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>
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!