Yesterday while adding support for multi-cultural stylesheets to one of the sites I'm currently working on,
I decided to rethink the way I usually implement this very common task. Until yesterday, I will have two literals
hosting the links tags each one pointing to a different stylesheet file, on my code behind I will check the current culture
and show the literal hosting the proper stylesheet link.
Well, that was, until yesterday, because I decided I wanted to create an easier way to accomplish this and not to settle
for the not-so-elegant but convenient copy-and-paste :-)
After searching for possible solutions already available I found this article on weblogs.asp.net and I used it as start point
for my control.
This is the custom control I finally came with:
[DefaultProperty("Text")]
[ToolboxData("<{0}:LinkExtended runat=server>")]
public class LinkExtended : System.Web.UI.WebControls.WebControl
{
#region
Constants private const string CULTURE_DEFAULT = "en-CA";
#endregion
#region
Fields protected bool isDesignMode = false;
protected string linkUrl = "";
protected string linkType = "";
protected string linkRelationship = "";
protected string defaultCulture = CULTURE_DEFAULT;
protected bool useUICulture = true;
#endregion
#region
Constructor public LinkExtended() : base()
{
this.isDesignMode = (System.ComponentModel.LicenseManager.UsageMode ==
System.ComponentModel.LicenseUsageMode.Designtime);
}
#endregion
#region
Protected Methods protected override void Render(HtmlTextWriter writer)
{
// Retrieve current culture
string cultureName = this.DefaultCulture;
if (!this.isDesignMode && this.UseUICulture)
cultureName = Thread.CurrentThread.CurrentUICulture.Name;
// parse link url
this.LinkUrl = this.LinkUrl.Replace("{culture}", cultureName);
// Render control
writer.WriteBeginTag("link");
writer.WriteAttribute("type",this.LinkType);
writer.WriteAttribute("rel",this.LinkRelationship);
writer.WriteAttribute("href",base.ResolveUrl(this.LinkUrl));
foreach (string key in this.Attributes.Keys)
{
writer.WriteAttribute(key,this.Attributes[key]);
}
writer.Write(HtmlTextWriter.TagRightChar);
writer.WriteEndTag("link");
}
protected override object SaveViewState()
{
object[] newstate = new object[5];
newstate[0] = (object)this.linkType;
newstate[1] = (object)this.linkRelationship;
newstate[2] = (object)this.linkUrl;
newstate[3] = (object)this.defaultCulture;
newstate[4] = (object)this.useUICulture;
return newstate;
}
protected override void LoadViewState(object savedState)
{
object[] newstate = (object[])savedState;
this.linkType = (string)newstate[0];
this.linkRelationship = (string)newstate[1];
this.linkUrl = (string)newstate[2];
this.defaultCulture = (string)newstate[3];
this.useUICulture = (bool)newstate[4];
}
#endregion
#region
Propeties [DefaultValue("")]
[Category("Appearance")]
[Description("The type html attribute.")]
[Bindable(true)]
public virtual string LinkType
{
get {return linkType;}
set {linkType = value;}
}
[DefaultValue("")]
[Category("Appearance")]
[Description("The rel html attribute.")]
[Bindable(true)]
public virtual string LinkRelationship
{
get {return linkRelationship;}
set {linkRelationship = value;}
}
[DefaultValue("")]
[Category("Appearance")]
[Description("The href html attribute.")]
[Bindable(true)]
public virtual string LinkUrl
{
get {return linkUrl;}
set {linkUrl = value;}
}
[DefaultValue(CULTURE_DEFAULT)]
[Category("Appearance")]
[Description("The default culture.")]
[Bindable(true)]
public virtual string DefaultCulture
{
get {return defaultCulture;}
set {defaultCulture=value;}
}
[DefaultValue(true)]
[Category("Appearance")]
[Description("If true the current UI Culture will be used at runtime.")]
[Bindable(true)]
public virtual bool UseUICulture
{
get {return useUICulture;}
set {useUICulture = value;}
}
#endregion
}
And then, just by adding the following line to my pages I get the desired functionality:
Hope this helps... :-)