代码之家  ›  专栏  ›  技术社区  ›  user989988

如何获取.resx文件ASP.NET核心[副本]

  •  0
  • user989988  · 技术社区  · 6 年前

    我正在使用.resx文件设计一个多语言应用程序。

    问题是: 我有一个包含所有可用语言的组合框,但我正在手动加载:

    comboLanguage.Items.Add(CultureInfo.GetCultureInfo("en"));
    comboLanguage.Items.Add(CultureInfo.GetCultureInfo("es"));
    

    我试过了

    cmbLanguage.Items.AddRange(CultureInfo.GetCultures(CultureTypes.UserCustomCulture));
    

    有没有办法只得到支持的语言?

    0 回复  |  直到 14 年前
        1
  •  47
  •   Hans Holzbart    13 年前

    您可以以编程方式列出应用程序中可用的区域性

    // Pass the class name of your resources as a parameter e.g. MyResources for MyResources.resx
    ResourceManager rm = new ResourceManager(typeof(MyResources));
    
    CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
    foreach (CultureInfo culture in cultures)
    {
        try
        {
            ResourceSet rs = rm.GetResourceSet(culture, true, false);
            // or ResourceSet rs = rm.GetResourceSet(new CultureInfo(culture.TwoLetterISOLanguageName), true, false);
            string isSupported = (rs == null) ? " is not supported" : " is supported";
            Console.WriteLine(culture + isSupported);
        }
        catch (CultureNotFoundException exc)
        {
            Console.WriteLine(culture + " is not available on the machine or is an invalid culture identifier.");
        }
    }
    
        2
  •  5
  •   George Birbilis    9 年前

    public static IEnumerable<CultureInfo> GetAvailableCultures()
    {
      List<CultureInfo> result = new List<CultureInfo>();
    
      ResourceManager rm = new ResourceManager(typeof(Resources));
    
      CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
      foreach (CultureInfo culture in cultures)
      {
        try
        {
          if (culture.Equals(CultureInfo.InvariantCulture)) continue; //do not use "==", won't work
    
          ResourceSet rs = rm.GetResourceSet(culture, true, false);
          if (rs != null)
            result.Add(culture);
        }
        catch (CultureNotFoundException)
        {
          //NOP
        }
      }
      return result;
    }
    

    使用该方法,可以获得要添加到某个组合框的字符串列表,其中包含以下内容:

    public static ObservableCollection<string> GetAvailableLanguages()
    {
      var languages = new ObservableCollection<string>();
      var cultures = GetAvailableCultures();
      foreach (CultureInfo culture in cultures)
        languages.Add(culture.NativeName + " (" + culture.EnglishName + " [" + culture.TwoLetterISOLanguageName + "])");
      return languages;
    }
    
        3
  •  4
  •   Ankush Madankar    9 年前


    特定语言的每个附属程序集的名称相同,但位于以特定区域性命名的子文件夹中,例如fr或fr-CA。

    public IEnumerable<CultureInfo> GetSupportedCulture()
    {
        //Get all culture 
        CultureInfo[] culture = CultureInfo.GetCultures(CultureTypes.AllCultures);
    
        //Find the location where application installed.
        string exeLocation = Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path));
    
        //Return all culture for which satellite folder found with culture code.
        return culture.Where(cultureInfo => Directory.Exists(Path.Combine(exeLocation, cultureInfo.Name)));
    }
    
        4
  •  2
  •   Rune Grimstad    16 年前

    如果找不到区域性特定的文件,则.NET将回退到区域性无关的资源,以便您可以安全地选择不受支持的语言。

    只要您自己控制应用程序,就可以将可用语言存储在某个应用程序设置中。只有一个用逗号分隔的字符串和区域性名称就足够了:“en,es”

        5
  •  2
  •   Tute    16 年前

    string executablePath = Path.GetDirectoryName(Application.ExecutablePath);
    string[] directories = Directory.GetDirectories(executablePath);
    foreach (string s in directories)
    {
        try
        {
            DirectoryInfo langDirectory = new DirectoryInfo(s);
            cmbLanguage.Items.Add(CultureInfo.GetCultureInfo(langDirectory.Name));
        }
        catch (Exception)
        {
    
        }
    }
    

    或其他方式

    int pathLenght = executablePath.Length + 1;
    foreach (string s in directories)
    {
        try
        {
            cmbLanguage.Items.Add(CultureInfo.GetCultureInfo(s.Remove(0, pathLenght)));
        }
        catch (Exception)
        {
    
        }
    }
    

        6
  •  1
  •   crokusek    5 年前

    指定要搜索的资源类型的泛型答案。使用反射但被缓存。

    List<string> comboBoxEntries = CommonUtil.CulturesOfResource<GlobalStrings>()
        .Select(cultureInfo => cultureInfo.NativeName)
        .ToList();
    

    实现(实用程序类):

    static ConcurrentDictionary<Type, List<CultureInfo>> __resourceCultures = new ConcurrentDictionary<Type, List<CultureInfo>>();
    
    /// <summary>
    /// Return the list of cultures that is supported by a Resource Assembly (usually collection of resx files).
    /// </summary>
    static public List<CultureInfo> CulturesOfResource<T>()
    {
        return __resourceCultures.GetOrAdd(typeof(T), (t) =>
        {
            ResourceManager manager = new ResourceManager(t);
            return CultureInfo.GetCultures(CultureTypes.AllCultures)
                .Where(c => !c.Equals(CultureInfo.InvariantCulture) && 
                            manager.GetResourceSet(c, true, false) != null)
                .ToList();
        });
    }
    

    它可能会遇到与接受的答案相同的问题,因为可能会加载所有语言资源。

        7
  •  0
  •   Tiago Freitas Leal    7 年前

    @“Ankush Madankar”提出了一个有趣的起点,但它有两个问题: 2) 找不到基本汇编语言的资源

    我不会试图解决问题2)但是对于问题1)代码应该是

    public List<CultureInfo> GetSupportedCultures()
    {
        CultureInfo[] culture = CultureInfo.GetCultures(CultureTypes.AllCultures);
    
        // get the assembly
        Assembly assembly = Assembly.GetExecutingAssembly();
    
        //Find the location of the assembly
        string assemblyLocation =
            Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(assembly.CodeBase).Path));
    
        //Find the file anme of the assembly
        string resourceFilename = Path.GetFileNameWithoutExtension(assembly.Location) + ".resources.dll";
    
        //Return all culture for which satellite folder found with culture code.
        return culture.Where(cultureInfo =>
            assemblyLocation != null &&
            Directory.Exists(Path.Combine(assemblyLocation, cultureInfo.Name)) &&
            File.Exists(Path.Combine(assemblyLocation, cultureInfo.Name, resourceFilename))
        ).ToList();
    }