【问题标题】:Xamarin iOS localization using .NET使用 .NET 进行 Xamarin iOS 本地化
【发布时间】:2014-01-01 09:25:07
【问题描述】:

我正在尝试在 Xamarin iOS/Android 项目的可移植类库中使用 .NET 本地化。我已按照以下步骤操作:

How to use localization in C#

并且有如下代码:

string sText = strings.enter_movie_name;
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr");
sText = strings.enter_movie_name;
lblEnterMovieName.Text = sText;

我也试过了:

ResourceManager resman = new ResourceManager(typeof(MyApplication.strings));
string sText = resman.GetString("enter_movie_name", new CultureInfo("fr"));

我创建了 strings.resx,其中 enter_movie_name 等于“输入电影名称:”,strings.fr.resx 等于“Entre la 电影名称:”

但是,sText 总是以“输入电影名称:”结尾。我似乎无法获得“Entre la movie name:”版本。

我也在Cross-platform Localization 看到了帖子,但无法解决。我也不想在Localization on Xamarin.iOS 使用 iOS 特定版本,因为我希望能够从独立于平台的库中获取我的字符串。

谁能指出我哪里出错了?

【问题讨论】:

  • 我实际上只是在这里发布了一个类似的问题:stackoverflow.com/questions/20608106/… 似乎特定于语言的 resx 文件(strings.fr.resx)被“编译”到 fr\MyApplication.resources.dll 中t 嵌入到应用程序中。因此它总是选择默认值。

标签: c# android ios localization xamarin


【解决方案1】:

我创建了一些丑陋的解决方案,但它确实有效。我所做的是在我的可移植类库 (PCL) 中创建了一个名为“strings”的文件夹,并在其中创建了名为:

  • strings.resx
  • strings_fr.resx
  • strings_ja_JP.resx

我已将这些所有设置为嵌入式资源,并使用自定义工具作为 ResXFileCodeGenerator。这意味着我对每种语言都有一个单独的资源 DLL。

在 iOS 中,我可以通过以下方式获取语言环境:

string sLocale = NSLocale.CurrentLocale.LocaleIdentifier;

我猜想有一个使用 Locale 的 Android 等价物,但我不知道它是什么。

这给了我一个类似“ja_JP”或“fr_FR”或“en_GB”的字符串(注意它们是下划线,而不是破折号)。然后我将它与我创建的以下静态类一起使用,以检索适当的资源管理器并从中获取字符串。

如果给定一个语言环境 aa_BB,它首先查找 strings_aa_BB,然后查找 strings_aa,然后查找 strings。

public static class Localise
{
    private const string STRINGS_ROOT = "MyPCL.strings.strings";

    public static string GetString(string sID, string sLocale)
    {
        string sResource = STRINGS_ROOT + "_" + sLocale;
        Type type = Type.GetType(sResource);
        if (type == null)
        {
            if (sLocale.Length > 2) {
                sResource = STRINGS_ROOT + "_" + sLocale.Substring(0, 2); // Use first two letters of region code
                type = Type.GetType(sResource);
            }
        }
        if (type == null) {
            sResource = STRINGS_ROOT;
            type = Type.GetType(sResource);
            if (type == null)
            {
                System.Diagnostics.Debug.WriteLine("No strings resource file when looking for " + sID + " in " + sLocale);
                return null; // This shouldn't ever happen in theory
            }
        }
        ResourceManager resman = new ResourceManager(type);
        return resman.GetString(sID);
    }
}

如何使用它的一个例子(参考上面的代码)是:

string sText = Localise.GetString("enter_movie_name", sLocale);
lblEnterMovieName.Text = sText;

这样做的一个显着缺点是所有视图都需要以编程方式设置其文本,但确实有好处,即翻译可以完成一次,然后在许多平台上重复使用。它们还与自己的 DLL 中的主代码保持分离,因此可以在必要时单独重新编译。

【讨论】:

    【解决方案2】:

    我创建了一个与接受的答案类似的解决方案,但使用 txt 文件而不是 Resx 和准备就绪的 nuget:https://github.com/xleon/I18N-Portable。博文here

    其他改进包括:

    • "anyKey".Translate(); // from anywhere
    • 自动检测当前区域性
    • 获取支持的翻译列表:List<PortableLanguage> languages = I18N.Current.Languages;
    • 支持 Mvvm 框架/Xamarin.Forms 中的数据绑定

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      • 2013-08-23
      • 1970-01-01
      • 2015-05-20
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      相关资源
      最近更新 更多