Making Your Own Semantic Controls
(
Apr 27 2007 - 06:02:26 PM by
Timothy Khouri) - [
print article]
ASP.NET Not Always Semantic
With the current thrust of the Internet moving towards "Semantic Markup" and clean HTML, you may begin to find that some ASP.NET controls that you are using render their HTML incorrectly such as a CheckBoxList using a <table> tag to render it's children, or even an ASP.NET AJAX UpdatePanel forcing either a <div> or <span> tag when you may want to render to a <label> or <fieldset> tag, etc..
While I always recommend using the .NET controls if they render semantically, I do also recommend overriding the default rendering in some cases to achieve clean, semantic markup. I'll demonstrate how to overcome the bad HTML rendering of the two above mentioned controls.
First we will make the SemanticUpdatePanel class. This class is exactly like the ASP.NET AJAX UpdatePanel that was made by Microsoft, but it adds a couple of features. The most important being the ability to choose what HTML tag should be rendered. Second, we will make our own SemanticCheckBoxList control that will render our checkboxes in a <ul> tag because it truthfuly is an "unordered list." Some people may want to argue that this is an "ordered list" and should therefore be rendered in a <ol> tag, but that's a different topic. First we should probably discuss briefly the issue.
What is Semantic Markup?
The word "semantic" means basically that something has "meaning." In the case of HTML tags, the "tag" has to represent the "content" inside of it. In other words, an <ol> tag (which stands for "Ordered List") should ONLY be used to represent an ordered list of data. If the data wasn't ordered (meaning it wasn't either in alphabetical order, or in numeric order etc.) then you would use ONLY a <ul> tag because that stands for "Unordered List."
Probably the most abused HTML tag would be the <table> tag, because people use it to layout their website visually, instead of using it to display only tabular data. This will be discussed more fully in an article in the "Standards" section of this site, but for now, on to the code!
By the way, for the "UpdatePanel" you need to have the ASP.NET AJAX DLL referenced in your web project.
using System;
using System.Web.UI;
using System.ComponentModel;
public class SemanticUpdatePanel : UpdatePanel
{
private HtmlTextWriterTag renderedElement = HtmlTextWriterTag.Div;
public HtmlTextWriterTag RenderedElement
{
get
{
return this.renderedElement;
}
set
{
this.renderedElement = value;
}
}
protected override void RenderChildren(HtmlTextWriter writer)
{
ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page);
if (scriptManager.IsInAsyncPostBack)
{
base.RenderChildren(writer);
return;
}
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
writer.RenderBeginTag(this.renderedElement);
base.Controls[0].RenderControl(writer);
writer.RenderEndTag();
}
}
That was very simple to do. But you might be wondering how I knew to override the "RenderChildren" method, not to mention how I knew that we need to check to see if we are in an async post-back and then adjust accordingly, right? Well the answer to that is simple, I used ".NET Reflector" created by Lutz Roeder to show me the code behind the UpdatePanel.
So now that we have the C# code, we need to see how easy it is to use this control in our HTML. Here it is:
<SingingEels:SemanticUpdatePanel ID="myUpdatePanel" runat="server" RenderedElement="Marquee">
<ContentTemplate>
Who uses a "Marquee" tag these days?
</ContentTemplate>
</SingingEels:SemanticUpdatePanel>
So now we have the C# code and the ASP.NET code that would be needed to make our own semantic control. Do to time and space issues, I'll have to write another article to address the SemanticCheckboxList control.