Introduction
This code shows how to do a simple localizable dropdown that sets up the options from a suitable text format. I had the usual HTML <select...>
with many <option...>
s and I wanted to have a localizable dropdown that could catch such data as a list of "<option>
" tags or maybe a list of any other data. The problem is that the standard ASP.NET 2.0 dropsown allows getting text from resources, but only for each option, not for whole dropdown control. So the custom dropdown should:
- Be simple and easy-to use.
- Be localizable (i.e., catch data from resources).
- Not request any additional code to write.
Using the code
After some thought and getting advices, I decided that the only good way is to create a successor of the standard dropdown control. The first step is to create our custom dropdown class in the App_Code folder. Before the class declaration, put the following code:
[DefaultProperty("InnerText"),
ToolboxData("<{0}:CustomDropDown runat="server">")]
Here we specify the default tag for our control. Then we should add the member for the text to be parsed:
private string innerText;
[Localizable(true)]
<Bindable(true), Category("Appearance"), DefaultValue("")>
public string InnerText
{
get
{
return innerText;
}
set
{
innerText = value;
}
}
Our future property will be appearing in the "Appearance" category and will have a value "". Then we add the Prepare
method that parses the text and fills the items of the dropdown list:
public void Prepare()
{
if (innerText == string.Empty || innerText == "")
return;
if (Items.Count > 0)
return;
string sep = separator == "" ? "@" : separator;
innerText = innerText.Replace("</option /><option />", sep);
innerText = innerText.Replace("</option />\r\n<option />", sep);
innerText = innerText.Replace("</option />", "");
innerText = innerText.Replace("<option />", "");
innerText = innerText.Replace("—", "-");
innerText = innerText.Replace("'", "'");
string[] cc = innerText.Split(new string[] { sep },
StringSplitOptions.RemoveEmptyEntries);
foreach (string c in cc)
{
this.Items.Add(new ListItem(c));
}
}
It's very simple. It just splits the string, deletes the extra tags (like "<option>
") between items, and fills the list. The only thing to describe more is the separator. It allows us to use the source text in different formats. It can be the usual "comma-separated values" or a real list of "<options...></options>
" tags. At first, we just replace the source separated by our separator and then split the string. For example, if we have the list of tags, we could use the "," separator, but we will have a problem if our string has the "," symbol itself. In this case, it will be better to use another separator, for example, "@". And such a separator will be the default. We add the separator declaration like:
private string separator = "";
[Localizable(true)]
<Bindable(true), Category("Appearance"), DefaultValue("")>
public string Separator
{
get
{
return separator;
}
set
{
separator = value;
}
}
We call the Prepare
method while the page is loading:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Prepare();
}
Then we should set up the culture. The best place for the code is the page's method InitializeCulture
:
protected override void InitializeCulture()
{
string lang = "en-US";
if (Request.QueryString["lang"] != null)
{
switch (Request.QueryString["lang"])
{
case "rus":
lang = "ru-RU";
break;
case "eng":
lang = "en-US";
break;
}
}
System.Globalization.CultureInfo ci = new
System.Globalization.CultureInfo(lang);
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
base.InitializeCulture();
}
That is a special method and is called very early before creating any controls. In this example, we set up one of two cultures: English or Russian (you can use as many languages as you want). We toggle the culture by clicking on the links:
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="~/Default.aspx?lang=rus">rus</asp:HyperLink>
<asp:HyperLink ID="HyperLink2" runat="server"
NavigateUrl="~/Default.aspx?lang=eng">eng</asp:HyperLink>
Every link passes the corresponding "lang
" parameter. The next step is to add our control to the page:
<ddc:CustomDropDown ID="Countries"
InnerText="<%$ Resources:Resource, CountriesCombo%>"
runat="server" Width="320px" style="margin-top:5px"
Separator="@"></ddc:CustomDropDown>
Don't forget to register our control:
<%@ Register Namespace="CustomControls" TagPrefix="ddc" %>
Finally we should add the resource. In the given sample, we are creating three resources files - Resource.resx, Resource.en-US.resx, and Resource.ru-RU.resx in App_GlobalResources. Then in every file, we add a new item named CountriesCombo
and put the text in it. Then we compile the project... Voila!