11

C# で ASP.NET を使用して MultiLanguage Web サイトを開発しようとしています。私の問題は、MasterPage で言語間の切り替えをサポートしたいのですが、masterpage.cs 内に「InitializeCulture()」を配置すると、次のようになりました。エラー。

これは私のコードです:

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();
}
}

基本クラスを作成するにはどうすればよいですか?

4

2 に答える 2

14

このメソッドは、 MasterPageクラスではなくPageクラスにInitializeCulture()のみ存在するため、そのエラーが発生します。

これを修正するにはBasePage、特定のすべてのページが継承する を作成します。

  1. 新しいクラス (Web フォームではない) を作成し、それBasePageを 、または任意の名前で呼び出します。
  2. System.Web.UI.Pageを継承させます。
  3. 他のすべてのページが を継承するようにしBasePageます。

次に例を示します。

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.
}
于 2012-08-20T13:30:52.277 に答える
9

BasePage を作成する必要がない代替ソリューションがあります。

'Culture' の問題は、ページのライフ サイクルの非常に早い段階で設定されることです。そのため、Page.InitializeCultureイベントはページの初期のイベントの 1 つであり (唯一のイベントではないにしても)、接続して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 値を更新するクライアント側のクリック イベントが実行されます。

マスター ページのヘッド セクションに Cookie を設定する JavaScript コードがあります。

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"andを設定してください。 にはOnClientChangedプロパティがないため、の属性をDropDownListハードコーディングし、選択した値を同じ JavaScript 関数に渡す必要があります。onchangeDropDownList

<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コントロールのアナログ コントロールであるため、属性はレンダリング時に「そのまま」配置され、ポストバック メカニズム コードの前にレンダリングされます。上記でレンダリングされた HTML は次のとおりです。DropDownListDropDownList<select>DropDownList

<select name="ctl00$cph1$ddlLanguage" onchange="SetLanguageCookie(this.options[this.selectedIndex].value);setTimeout(&#39;__doPostBack(\&#39;ctl00$cph1$ddlLanguage\&#39;,\&#39;\&#39;)&#39;, 0)" id="cph1_ddlLanguage">
  <option value="en">English</option>
  <option value="es">Español</option>
  <option value="fr">Français</option>
</select>

誰かがこのアプローチが私と同じくらい役立つことを願っています。:)

于 2016-03-10T23:20:00.917 に答える