【问题标题】:Replacement for CultureInfo.GetCultures in .NET Windows Store apps.NET Windows Store 应用程序中 CultureInfo.GetCultures 的替换
【发布时间】:2012-09-18 21:50:55
【问题描述】:

适用于 Windows 应用商店应用的 .NET API 中不存在 CultureInfo.GetCultures。我们如何才能阅读所有可用的文化?

我了解语言列表和主要应用程序语言。我可以通过这种方式阅读应用程序可用的所有语言。但我需要阅读系统上可用的所有文化(语言)。以前使用 CultureInfo.GetCultures 很容易。

【问题讨论】:

  • EnumSystemLocalesEx 可用。我不知道这是否以某种方式投射到.NET;我没有看到任何 Windows 运行时 API。
  • 谢谢,詹姆斯。看起来我们必须使用 Win32 api。微软可能会在未来将此添加到 WinRT。
  • 为什么需要这个?你对结果做了什么?
  • @Eric:我只是需要它来为我的新书做一个演示应用程序。如果您的问题指向是否需要在现实世界的应用程序中检索所有文化,我怀疑这是否会经常发生在 Windows 应用商店应用程序中。但你永远不知道。无论如何我找到了解决方案(请参阅我自己的答案)。
  • 鉴于有大约 6000 种语言,随着 Microsoft 添加对新语言的支持,我们最终会遇到枚举语言没有帮助的地步。有专门的列表而不是通用列表(请参阅 Windows.System.UserProfile.GlobalizationPreferences.Languages 和 Windows.Globalization.ApplicationLanguages)。 Windows.Globalization.Language.IsWellFormed 还针对 BCP47 格式良好的约束进行验证。如果有这些未涵盖的场景,我很想了解它们。

标签: c# windows-runtime microsoft-metro windows-store-apps


【解决方案1】:

James 的评论为我指明了正确的方向。这是我开发的代码。我使用单元测试检查了代码,以确保返回的中性、特定和所有文化与 CultureInfo.GetCultures 返回的文化相同(它们确实是:-))。

public class LocalesRetrievalException : Exception
{
    public LocalesRetrievalException(string message)
        : base(message)
    {
    }
}

public static class CultureHelper
{
    #region Windows API

    private delegate bool EnumLocalesProcExDelegate(
       [MarshalAs(UnmanagedType.LPWStr)]String lpLocaleString,
       LocaleType dwFlags, int lParam);

    [DllImport(@"kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool EnumSystemLocalesEx(EnumLocalesProcExDelegate pEnumProcEx,
       LocaleType dwFlags, int lParam, IntPtr lpReserved);

    private enum LocaleType : uint
    {
        LocaleAll = 0x00000000,             // Enumerate all named based locales
        LocaleWindows = 0x00000001,         // Shipped locales and/or replacements for them
        LocaleSupplemental = 0x00000002,    // Supplemental locales only
        LocaleAlternateSorts = 0x00000004,  // Alternate sort locales
        LocaleNeutralData = 0x00000010,     // Locales that are "neutral" (language only, region data is default)
        LocaleSpecificData = 0x00000020,    // Locales that contain language and region data
    }

    #endregion

    public enum CultureTypes : uint
    {
        SpecificCultures = LocaleType.LocaleSpecificData,
        NeutralCultures = LocaleType.LocaleNeutralData,
        AllCultures = LocaleType.LocaleWindows
    }

    public static IReadOnlyCollection<CultureInfo> GetCultures(
       CultureTypes cultureTypes)
    {
        List<CultureInfo> cultures = new List<CultureInfo>();
        EnumLocalesProcExDelegate enumCallback = (locale, flags, lParam) =>
        {
            try
            {
                cultures.Add(new CultureInfo(locale));
            }
            catch (CultureNotFoundException)
            {
                // This culture is not supported by .NET (not happened so far)
                // Must be ignored.
            }
            return true;
        };

        if (EnumSystemLocalesEx(enumCallback, (LocaleType)cultureTypes, 0,
           (IntPtr)0) == false)
        {
            int errorCode = Marshal.GetLastWin32Error();
            throw new LocalesRetrievalException("Win32 error " + errorCode +
               " while trying to get the Windows locales");
        }

        // Add the two neutral cultures that Windows misses 
        // (CultureInfo.GetCultures adds them also):
        if (cultureTypes == CultureTypes.NeutralCultures ||
           cultureTypes == CultureTypes.AllCultures)
        {
            cultures.Add(new CultureInfo("zh-CHS"));
            cultures.Add(new CultureInfo("zh-CHT"));
        }

        return new ReadOnlyCollection<CultureInfo>(cultures);
    }
}

【讨论】:

    猜你喜欢
    • 2012-09-20
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多