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

这是我的默认区域设置: 区域设置

运行时,应用程序以芬兰语格式显示日期:

芬兰语格式

然后我将区域设置更改为美国: 美国地区设置

当应用程序再次运行时,文化和格式发生了变化: 美国 wpf 格式

这是我期望的一切工作,这也是我期望 WinRT 应用程序工作的方式。

因此,下一步,我使用相同的代码创建了一个 WinRT(XAML 和 C#)应用程序,并将区域设置恢复为芬兰语。问题:

Winrt 格式化

即使我通过区域设置定义了格式应该是“芬兰语”,WinRT 应用程序也会使用美国格式显示日期时间。然后我修改了应用程序的项目文件并将fi-FI 设为默认语言

默认语言

此更改还修改了应用程序的文化:

芬兰语 winrt 格式

奇怪的。我将默认语言更改回其默认值,并且格式恢复为美国。然后我在项目中创建了文件夹“Strings - fi-FI”,并在项目中添加了一个空的“Resources.resw”。这个空文件似乎就足够了,因为我现在正在获取芬兰语格式:

资源文件 芬兰语格式

一旦我删除了空的资源文件,格式就会恢复为 US:

资源文件已移除 美国格式化winrt

很奇怪。

这会导致几个问题,但我认为主要的问题是:WinRT 应用程序是否有意不遵循 WPF 应用程序那样的用户区域设置?

4

4 回答 4

15

已经有一段时间了,但这个问题还没有完全回答,所以让我分享一下我的小研究。Depechie 基本上是对的,但他只提供了一个链接,并不确定。

是的,这种意想不到的变化是故意的。我们不应再使用 CultureInfo,因为它包含遗留代码,而微软希望我们改用 Windows.Globalization API。

要获取当前区域,我们可以使用:

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)

如果语言有方言,它们会以语言区域格式返回 BCP47 语言标签,如“en-US”,如果语言没有主要方言,则返回“pl”之类的语言。

我们还可以设置一种主要语言来覆盖所有其他语言:

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

这是故意的。微软正在不再强制应用程序使用操作系统的语言。相反,每个应用程序使用应用程序声明的信息(清单语言,可在 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

尽管两年前有人问过这篇文章,但它似乎仍然具有相关性。我只是在寻找关于同一件事的答案时偶然发现了它。我还想在我的 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 回答