21

ユーザーの地域設定に関して、Windows 8 Metro アプリ (XAML & C#) で問題が発生しています。アプリはユーザーの地域設定を尊重しないようです。そのため、Windows 8 がフィンランド語形式で日付と時刻を表示するように設定されていても、アプリは米国形式を使用して表示します。しかし、これは私が見逃している何かがあるに違いないほど大きな問題ですか?

これをテストするために、WPF-applicationを作成することから始めました。アプリケーションは、CurrentCulture とフォーマットされた DateTime.Now を出力するだけです。

    private void Culture_Loaded_1(object sender, RoutedEventArgs e)
    {
        this.Culture.Text = System.Globalization.CultureInfo.CurrentCulture.DisplayName;
    }

    private void Date_Loaded_1(object sender, RoutedEventArgs e)
    {
        this.Date.Text = DateTime.Now.ToString();
    }

これが私のデフォルトの地域設定です: 地域の設定

実行すると、アプリはフィンランド語の形式で日付を表示しました。

フィンランド語の書式設定

次に、地域設定を米国に変更しました。 米国の地域設定

アプリを再度実行すると、カルチャと書式設定が変更されました。 US wpf フォーマット

これはすべてが機能することを期待したとおりであり、WinRT アプリが機能することを期待した方法でもあります。

次のステップとして、同じコードで WinRT (XAML & C#) アプリを作成し、地域設定をフィンランド語に戻しました。問題:

Winrt フォーマット

書式設定が "フィンランド語" であることを地域設定で定義した場合でも、WinRT アプリは日時を米国形式で表示します。次に、アプリのプロジェクト ファイルを変更し、fi-FI を既定の言語にしました

既定の言語

この変更により、アプリのカルチャも変更されました。

フィンランドの winrt 形式

変。デフォルトの言語をデフォルト値に戻すと、書式設定が US に復元されました。次に、プロジェクト内に「Strings - fi-FI」フォルダーを作成し、プロジェクトに空の「Resources.resw」を追加しました。フィンランド語のフォーマットを取得しているので、この空のファイルで十分なようです。

リソースファイル フィンランド語の書式設定

空のリソース ファイルを削除するとすぐに、書式設定が US に戻ります。

リソース ファイルが削除されました 米国形式の winrt

非常に奇妙な。

これはいくつかの質問につながりますが、私が思う主な質問は、WinRT アプリが WPF アプリのようにユーザーの地域設定に従わないのは意図的なことですか?

4

4 に答える 4

15

しばらく経ちましたが、その質問には完全には答えられていないので、私の小さな研究を共有させてください. Depechie はおおむね正しいですが、彼はリンクを提供しただけで、よくわかりませんでした。

はい、この予期しない変更は意図的なものです。CultureInfo にはレガシ コードが含まれており、Microsoft は代わりに Windows.Globalization API を使用することを望んでいるため、CultureInfo を使用しないでください。

現在の地域を取得するには、次を使用できます。

GeographicRegion userRegion = new GeographicRegion();
string regionCode = userRegion.CodeTwoLetter;

しかし、地域情報しか含まれていないことに気付きました。言語コードはありません。言語を取得するには、次を使用できます。

string langRegionCode = Windows.Globalization.Language.CurrentInputMethodLanguageTag; // depends on keyboard settings
List<string> langs = Windows.System.UserProfile.GlobalizationPreferences.Languages; // all user  languages, like in languages control panel
List<string> applicationlangs = Windows.Globalization.ApplicationLanguages.Languages; // application languages (user languages resolved against languages declared as supported by application)

言語に方言がある場合は "en-US" のような language-REGION の形式で BCP47 言語タグを返し、言語に主要な方言がない場合は "pl" のような言語だけを返します。

他のすべてを上書きする 1 つの主要言語を設定することもできます。

Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "en-US";

(これは永続的な設定であり、ユーザーの要求で使用されることになっています)

日付、時刻、数値用の新しい API もあります。

Windows.Globalization.DateTimeFormatting.DateTimeFormatter dtf = new DateTimeFormatter("longdate", new[] { "en-US" }, "US", CalendarIdentifiers.Gregorian, ClockIdentifiers.TwentyFourHour);
string longDate = dtf.Format(DateTime.Now);

Windows.Globalization.NumberFormatting.DecimalFormatter deciamlFormatter = new DecimalFormatter(new string[] { "PL" }, "PL");
double d1 = (double)deciamlFormatter.ParseDouble("2,5"); // ParseDouble returns double?, not double

Windows.Globalization API には実際にはもっと多くの機能がありますが、これで一般的なアイデアが得られると思います。さらに読むには:

また、Windows 8 デベロッパー センター フォーラムで、Microsoft 従業員の回答を含む問題に関するトピックをいくつか見つけることができますが、主にドキュメントに送られます。

于 2012-12-29T23:02:01.420 に答える
4

意図的なものです。Microsoftは、アプリケーションをOSの言語にすることを強制することから離れつつあります。代わりに、各アプリケーションは、アプリケーションによって宣言された情報(マニフェスト言語、Windows.Globalization.ApplicationLanguages.ManifestLanguagesで監視可能)とユーザーによって宣言された情報(ユーザー言語、Windows.System.UserProfile.GlobalizationPreferences.Languagesで監視可能)を使用して、表示方法を決定します。リソースとグローバル化された日時。この言語のセットは、アプリケーション言語と呼ばれます(Windows.Globalization.ApplicationLanguages.Languagesで確認できます)。あなたが見ている振る舞いは、ユーザー言語とマニフェスト言語をいじっていて、異なるアプリケーション言語を取得するためです。

于 2013-03-07T21:43:28.797 に答える
2

他のクラスを照会する必要があるのでしょうか? ここに示す例のように: http://code.msdn.microsoft.com/windowsapps/Globalization-preferences-6654eb36/sourcecode?fileId=52104&pathId=236099476

于 2012-09-25T17:13:37.633 に答える
0

この投稿は、2 年前に尋ねられたにもかかわらず、依然として関連性があるようです。ほぼ同じことへの答えを探していたので、ちょうどそれを見つけました。また、WP8.1 WinRT アプリで日付を地域形式で表示したいと考えていました。ここに投稿された情報は役に立ちますが、まとめるのは少し大変でした。

これは私が思いついたものであり、私が必要としていた答えとしてうまくいくようです:

using Windows.Globalization;
using Windows.Globalization.DateTimeFormatting;

private string FormatDate(int year, int month, int day)
{
    GeographicRegion userRegion = new GeographicRegion();
    string regionCode = userRegion.CodeTwoLetter;
    var formatter = new DateTimeFormatter("year month day", new[] { regionCode });
    DateTime dateToFormat = new DateTime(year, month, day);
    var formattedDate = formatter.Format(dateToFormat);
    return formattedDate;
}
于 2015-07-07T19:33:09.260 に答える