masterpage initializeculture没有找到合适的方法来覆盖错误?

时间:2012-08-04 04:27:47

标签: c# calendar

我正在尝试使用带有C#的ASP.NET开发一个MultiLanguage网站 我的问题是:我想让我的MasterPage支持在语言之间切换,但是当我把“InitializeCulture()”放在masterpage.cs中时,我收到了这个错误。

这是我的代码:

public partial class BasicMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
    if (e.Day.IsToday)
    {
        e.Cell.Style.Add("background-color", "#3556bf");
        e.Cell.Style.Add("font-weight", "bold");
    }
}
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();
}
}

如何创建基类?

2 个答案:

答案 0 :(得分:12)

方法InitializeCulture()仅存在于Page类,而不存在于MasterPage类,这就是您收到该错误的原因。

要解决此问题,您可以创建所有特定网页都继承的BasePage

  1. 创建一个新类(不是Webform),将其称为BasePage,或任何你想要的。
  2. 让它继承System.Web.UI.Page
  3. 让所有其他网页继承BasePage
  4. 以下是一个例子:

    public class BasePage : System.Web.UI.Page
    {
        protected override void InitializeCulture()
        {
            //Do the logic you want for all pages that inherit the BasePage.
        }
    }
    

    具体页面看起来应该是这样的:

    public partial class _Default : BasePage //Instead of it System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Your logic.
        }
    
        //Your logic.
    }
    

答案 1 :(得分:9)

有一个替代解决方案,不要求您创建BasePage。

“文化”的问题在于它在页面生命周期的早期设置,所以Page.InitializeCulture事件是页面上的早期事件之一(如果不是唯一的事件)我们可以挂机以更改Thread.CurrentThread.CurrentUICulture。但是,只要请求在服务器上开始,我们就会更早地做到这一点。

我在每个请求上调用的Application_BeginRequest文件的Global.asax事件上执行此操作。

protected void Application_BeginRequest(Object sender, EventArgs e)
{
  HttpCookie cookie = Request.Cookies["langCookie"];
  if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
  {
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
  }
}

在那里,我检查是否存在一个包含我想要使用的文化的cookie。如果没有cookie,则将使用默认文化。

要更改我的应用程序上的语言,我只需要一个控件来更改客户端的cookie值,然后对服务器进行简单的回发。如果此类控件位于内容页面或母版页中并不重要,它甚至不需要服务器端的任何代码,因为所有处理都是在上述方法上完成的,并且cookie设置为客户端甚至在页面发布之前。

我使用了一个简单的LinkBut​​ton(它被设计为墨西哥国旗),但是你可以使用任何其他控件来点击/更改后进行回发。

<asp:LinkButton ID="btnSpanish" runat="server" OnClientClick="SetLanguageCookie('es')" CausesValidation="false" CssClass="mxFlag" />

在此按钮回发到服务器之前,它运行客户端点击事件,更新我想要设置的cookie值,瞧!

我有javascript代码在主页面部分设置cookie:

function SetLanguageCookie(selectedLanguage) {
  var expDate = new Date();
  expDate.setDate(expDate.getDate() + 20); // Expiration 20 days from today
  document.cookie = "langCookie=" + selectedLanguage + "; expires=" + expDate.toUTCString() + "; path=/";
};

就是这样! Thread.CurrentThread.CurrentUICulture已更改,不需要BasePage类,也不会覆盖Page.InitializeCulture方法。由于存储在cookie中,所以在访问后会记住所选语言的副作用。

如果您想使用DropDownList而不是LinkButton,请务必设置AutoPostBack="true",因为{{没有OnClientChanged属性1}},您必须对DropDownList上的onchange属性进行硬编码,并将所选值传递给相同的javascript函数。

DropDownList

<asp:DropDownList ID="ddlLanguage" runat="server" AutoPostBack="true" onchange="SetLanguageCookie(this.options[this.selectedIndex].value)"> <asp:ListItem Text="English" Value="en" /> <asp:ListItem Text="Español" Value="es" /> <asp:ListItem Text="Français" Value="fr" /> </asp:DropDownList> 属性不是onchange属性的一部分,但是,因为DropDownListDropDownList控件的模拟控件,所以属性只是放置了'就像'渲染发生时一样,它在回发机制代码之前呈现。这是上面<select>呈现的HTML:

DropDownList

希望有人发现这种方法和我一样有用。 :)