I need to create an ASP.NET page that displays a Calendar control which shows a specific calendar based on value selected in a drop down. Currently I need to display HebrewCalendar and the regua开发者_运维知识库lr (gregorian) calendar, but in the future I'll probably need others. Of course I can't use the Regional Settings of Windows or the globalization definition in web.config since the required calendar is set in runtime. How can I display various calendars in a Calendar control?
Thanks!
The trick is you'll need to set the Culture of the current thread, and (for some locales like Hebrew) also need to set the Calendar within that Culture.
The self-contained code sample below illustrates how to do this. This approach of course may affect other controls's localized text. If this is a problem-- and you only want to localize the Calendar control and leave the rest in English-- then you can do the following:
- derive a class from ASP.NET's Calendar control and override the Render() method.
- in your Render() implementation, save the current thread's culture/UICulture, then reset the culture and calendar of the current thread using the code below, then call the base class's Render(), then restore the culture/UICulture of the curren thread
- use that class, instead of the regular ASP.NET calendar, in your ASPX page.
Here's the code:
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Globalization"%>
<%@ Import Namespace="System.Threading"%>
<%@ Import Namespace="System.Collections.Generic"%>
<html>
<body>
<form id="form1" runat="server">
Choose a language and calendar: <asp:DropDownList ID="LocaleChoice" runat="server" AutoPostBack="true">
<asp:ListItem Value="en-US" Selected="True">English</asp:ListItem>
<asp:ListItem Value="es-MX">Español</asp:ListItem>
<asp:ListItem Value="de-DE">Deutsch</asp:ListItem>
<asp:ListItem Value="he-IL|HebrewCalendar">Hebrew (Hebrew Calendar)</asp:ListItem>
<asp:ListItem Value="he-IL|GregorianCalendar">Hebrew (Gregorian Calendar)</asp:ListItem>
<asp:ListItem Value="ar-SA|HijriCalendar">Arabic (Hijri Calendar)</asp:ListItem>
<asp:ListItem Value="ar-SA|GregorianCalendar">Arabic (Gregorian Calendar)</asp:ListItem>
</asp:DropDownList><br /><br />
<asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>
</form>
</body>
</html>
<script runat="server">
Dictionary<string, System.Globalization.Calendar> Calendars =
new Dictionary<string, System.Globalization.Calendar>()
{
{"GregorianCalendar", new GregorianCalendar()},
{"HebrewCalendar", new HebrewCalendar()},
{"HijriCalendar", new HijriCalendar()},
{"JapaneseCalendar", new JapaneseCalendar()},
{"JulianCalendar", new JulianCalendar()},
{"KoreanCalendar", new KoreanCalendar()},
{"TaiwanCalendar", new TaiwanCalendar()},
{"ThaiBuddhistCalendar", new ThaiBuddhistCalendar ()}
};
protected override void InitializeCulture()
{
if (Request.Form["LocaleChoice"] != null)
{
string selected = Request.Form["LocaleChoice"];
string[] calendarSetting = selected.Split('|');
string selectedLanguage = calendarSetting[0];
CultureInfo culture = CultureInfo.CreateSpecificCulture(selectedLanguage);
if (calendarSetting.Length > 1)
{
string selectedCalendar = calendarSetting[1];
var cal = culture.Calendar;
if (Calendars.TryGetValue(selectedCalendar, out cal))
culture.DateTimeFormat.Calendar = cal;
}
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
base.InitializeCulture();
}
protected void Page_Load(object sender, EventArgs e)
{
}
</script>
If you need per-calendar culture customization have a look at BaseCalendar (there's a demo included that handles this scenario). Changing the current thread's culture could have side-effects in other places. BaseCalendar allows you to specify a culture for a calendar without changing the current thread's culture.
精彩评论