我在Windows 8 Metro应用程序(XAML& C#)中遇到有关用户区域设置的问题。似乎应用程序不会尊重用户的区域设置,因此即使您的Windows 8设置为以芬兰语格式显示日期和时间,应用程序仍将使用美国格式显示它们。但这是一个很大的问题,必须有一些我不知道的东西?
为了测试这一点,我首先创建了一个 WPF应用程序。应用程序只打印出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();
}
这是我的默认区域设置:
运行时,应用程序以芬兰语格式显示日期:
然后我将区域设置更改为美国:
当应用程序再次运行时,文化和格式发生了变化:
正如我预期的那样一切正常,这也是我期望WinRT应用程序的工作方式。
因此,下一步,我使用相同的代码创建了一个WinRT(XAML& C#)应用程序,并将区域设置恢复为芬兰语。问题:
即使我通过区域设置定义格式应为“芬兰语”,WinRT应用程序也会以美国格式显示日期时间。然后,我修改了应用程序的项目文件,并将 fi-FI设为默认语言:
此更改还修改了应用程序的文化:
奇怪。我将默认语言更改回其默认值,格式化已恢复为美国。然后我在项目中创建了文件夹“Strings-fi-FI”,并在项目中添加了空“Resources.resw”。这个空文件似乎已经足够了,因为我现在正在使用芬兰格式:
只要删除空资源文件,格式就会恢复为US:
很奇怪。
这引出的问题很少,但我认为主要的问题是:WinRT应用程序是否故意不按照WPF应用程序的用户区域设置进行操作?
答案 0 :(得分:15)
已经有一段时间了,但问题没有得到完全回答,所以让我分享一下我的小研究。 Depechie大多是对的,但他只提供了一个链接而且不太确定。
是的,这种意想不到的变化是故意的。我们不应该再使用CultureInfo了,因为它包含遗留代码,Microsoft要求我们使用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)
如果语言有方言,他们会以格式语言-REGION返回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员工的答案,但他们主要将您发送到文档。
答案 1 :(得分:4)
这是故意的。微软正逐渐迫使应用程序采用操作系统语言。相反,每个应用程序使用应用程序声明的信息(清单语言,在Windows.Globalization.ApplicationLanguages.ManifestLanguages中可观察)并由用户声明(用户语言,在Windows.System.UserProfile.GlobalizationPreferences.Languages中可观察)以确定如何显示资源和全球化的日期和时间。这组语言称为应用程序语言(在Windows.Globalization.ApplicationLanguages.Languages中可观察)。您看到的行为是因为您正在摆弄用户语言和清单语言,您将获得不同的应用程序语言。
答案 2 :(得分:2)
我们现在需要查询其他类吗?就像这里给出的例子一样:http://code.msdn.microsoft.com/windowsapps/Globalization-preferences-6654eb36/sourcecode?fileId=52104&pathId=236099476
答案 3 :(得分: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;
}