2012-09-24 69 views
21

我在Windows 8 Metro應用程序(XAML & C#)中遇到了有關用戶區域設置的問題。看來,應用程序將不會尊重用戶的區域設置,所以即使你的Windows 8被設置爲顯示日期和時間格式芬蘭的應用仍然會使用美國格式顯示。但是,這是一個很大的問題,我一定有一些東西丟失了?WinRT應用程序和區域設置。根據用戶的區域設置格式化日期和數字的正確方法是什麼?

爲了驗證這一點,我開始通過創建一個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(); 
    } 

這裏是我的默認區域設置: Regional settings

運行時,應用程序顯示在芬蘭格式的日期:

Finnish formatting

然後我將區域設置更改爲美國: US Regional settings

而當應用程序被再次運行,文化和格式更改: US wpf formatting

這是如我所料一切工作,這也是我沒有料到的WinRT應用工作。

因此,下一步,我創建了一個具有相同代碼的WinRT(XAML & C#)應用程序,並將區域設置恢復爲芬蘭語。問題:

Winrt formatting

即使我已經通過區域設置該格式應該是「芬蘭」定義的,WinRT的應用程序將顯示美國格式化的日期時間。然後我修改了應用程序的項目文件並提出FI-FI的默認語言

Default language

這一變化也修改了應用程序的文化:

Finnish winrt formatting

奇怪。我將默認語言更改回默認值,並將格式恢復爲美國。然後,我在項目內創建了文件夾「Strings-fi-FI」,並在項目中添加了一個空的「Resources.resw」。這個空文件似乎是不夠的,因爲我現在越來越芬蘭格式:當我刪除空資源文件

Resource file Finnish formatting

,將打印格式返回到美國:

Resource file removed US formatting winrt

很奇怪。

這導致了幾個問題,但我認爲的主要問題是:WinRT應用程序是否不像WPF應用程序那樣遵循用戶的區域設置?

回答

14

已經有一段時間了,但問題還沒有完全解答,所以讓我分享一下我的小研究。 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) 

他們返回格式語言地區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的多很多,但我認爲,這給我們的總體思路。進一步閱讀:

您還可以找到一些關於windo問題的主題ws 8開發中心論壇與一些微軟員工的答案,但他們主要向您發送文檔。

+3

所以,實際上可以如何獲取/尊重用戶分區格式設置? 我開始使用以下配置的windows phone 8.1仿真器進行測試: UI語言:德語,地區:美國,格式設置:愛爾蘭語 我找不到信息,用戶已將其格式設置愛爾蘭人。我唯一的願望是像用戶想要看到的那樣格式化日期時間。和區域格式不會自動意味着它的區域我將設備設置爲或我選擇的用戶界面語言。在我的設備上,我將用戶界面設置爲英文,但希望以德文格式查看所有時間戳記和日期... – Kornelis

+0

謝謝,以下內容非常棒,因爲我需要ISO 3166-1 alpha2 https://en.wikipedia.org/ wiki/ISO_3166-1_alpha-2 GeographicRegion userRegion = new GeographicRegion(); string regionCode = userRegion.CodeTwoLetter; – Quincy

+0

這對我有效,但現在我需要大數字和'CurrencyFormatter'不支持小數,所以我需要一個解決方法... –

4

這是故意的。微軟正在擺脫強迫應用程序成爲操作系統的語言。相反,每個應用程序使用由應用程序聲明的信息(清單語言,可在Windows.Globalization.ApplicationLanguages.ManifestLanguages中觀察到)並由用戶聲明(用戶語言,可在Windows.System.UserProfile.GlobalizationPreferences.Languages中觀察到)來確定如何顯示資源和全球化的日期和時間。這組語言被稱爲應用程序語言(可在Windows.Globalization.ApplicationLanguages.Languages中觀察到)。你所看到的行爲是因爲你在擺弄用戶語言和清單語言,你會得到不同的應用程序語言。

+4

有趣的方法,雖然作爲一個葡萄牙生活在英國(目前爲微軟工作),我couldn對此不再不同意!這是我的看法:我的Win10手機的語言設置爲「英語美國」,國家爲「英國」,地區格式爲「葡萄牙語(葡萄牙)」。 Outlook以正確的pt-PT格式顯示日期,但所有其他應用程序堅持使用en-US,這是恕我直言的錯誤,而不是我預期的! –

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; 
} 
相關問題