简体   繁体   English

Xamarin.Forms:如何使用独立于设备语言的本地化

[英]Xamarin.Forms : How to use localization independent of device language

I am developing a Xamarin.Forms app (portable class library project) with Visual Studio 2013 CE. 我正在使用Visual Studio 2013 CE开发一个Xamarin.Forms应用程序(可移植类库项目)。 First I'm focusing the iOS version. 首先我关注iOS版本。

Now I'm thinking about how to make the app multilingual. 现在我正在考虑如何使应用程序多语言。 I just read the offical Xamarin documentation about it but i realized that this solution only takes the system language of the target device. 我刚刚阅读了关于它的官方Xamarin文档,但我意识到这个解决方案只采用目标设备的系统语言。

In the portable class library I have a Resources folder with three languages: German (default), English and French. 在便携式类库中,我有一个包含三种语言的Resources文件夹:德语(默认),英语和法语。

Resource.resx
Resource.en-US.resx
Resource.fr-FR.resx
Resource.Designer.cs

Now i just created a static settings class which looks like this: 现在我刚刚创建了一个静态设置类,如下所示:

public static class Settings
{
    public static Dictionary<String, CultureInfo> Languages = new Dictionary<String, CultureInfo> { { "German", new CultureInfo("de-DE") }, { "English", new CultureInfo("en-US") }, { "French", new CultureInfo("fr-FR") } };

    public static CultureInfo CurrentCulture = Languages["German"];
    public static CultureInfo CurrentUiCulture = Languages["German"];

    public static void ChangeCurrentCultureInfo(CultureInfo cultureInfo)
    {
        Resource.Culture = cultureInfo;
    }
}

Now my question is if it's possible to change the culture in the application while runtime with a button click. 现在我的问题是,是否可以通过单击按钮更改运行时的文化。 Maybe something like 也许是这样的

Settings.CurrentCulture = Settings.Languages["English"];
Settings.ChangeCurrentCultureInfo(Settings.CurrentCulture);

Does anyone can tell me how this can be done? 有谁能告诉我这是怎么做到的?

Regards 问候

I don't believe you can do this from within your shared PCL project. 我不相信你可以在你的共享PCL项目中做到这一点。 However, you CAN set the UICulture from within your platform-specific projects. 但是,您可以在特定于平台的项目中设置UICulture。 To do this from a useful location (ie, your Forms app), we must expose this as a service from your platform projects as a dependency. 要从有用的位置(即您的Forms应用程序)执行此操作,我们必须将此作为服务从您的平台项目中公开为依赖项。

First, define the interface that describes your culture management "service." 首先,定义描述文化管理“服务”的界面。 This should live in an assembly that is referenced by your platform-specific projects (the shared PCL project will do): 这应该存在于特定于平台的项目引用的程序集中(共享PCL项目将执行此操作):

public interface ICultureInfo
{
    System.Globalization.CultureInfo CurrentCulture { get; set; }
    System.Globalization.CultureInfo CurrentUICulture { get; set; }
}

And in each of your platform projects, include a type that implements that interface: 在每个平台项目中,包含一个实现该接口的类型:

using System;
using Xamarin.Forms;
using System.Threading;

[assembly:Dependency(typeof(YourNamespaceHere.PlatformCultureInfo))]
namespace YourNamespaceHere
{
    public class PlatformCultureInfo : ICultureInfo
    {
        #region ICultureInfo implementation

        public System.Globalization.CultureInfo CurrentCulture {
            get {
                return Thread.CurrentThread.CurrentCulture;
            }
            set {
                Thread.CurrentThread.CurrentCulture = value;
            }
        }

        public System.Globalization.CultureInfo CurrentUICulture {
            get {
                return Thread.CurrentThread.CurrentUICulture;
            }
            set {
                Thread.CurrentThread.CurrentUICulture = value;
            }
        }

        #endregion
    }
}

Then in your forms app, you request an instance of the platform's implementation from the Xamarin Forms DependencyService. 然后在表单应用程序中,从Xamarin Forms DependencyService请求平台实现的实例。 (NOTE: Any calls to the DependencyService must happen AFTER a call to Forms.Init()) (注意:对DependencyService的任何调用必须在调用Forms.Init()之后发生)

Once you retrieve it, you can set the current UI culture: 检索后,您可以设置当前的UI文化:

var cultureInfo = Xamarin.Forms.DependencyService.Get<ICultureInfo>();
cultureInfo.CurrentUICulture = new System.Globalization.CultureInfo("fr-FR");

Et voila, any changes to the UI culture will be reflected with any subsequent resource lookups. 此外,对UI文化的任何更改都将反映在任何后续资源查找中。 Note the use of the word "subsequent" - any forms using resource lookups (such as if you're using my handy localization XAML markup extensions ) won't reflect the culture change until they are refreshed/reloaded. 请注意使用“后续”一词 - 使用资源查找的任何表单(例如,如果您使用我的方便的本地化XAML标记扩展 )将不会反映文化更改,直到它们被刷新/重新加载。

In closing, the Xamarin team did a great job duplicating the original resource lookup infrastructure! 最后,Xamarin团队在重复原始资源查找基础架构方面做得非常出色! It just needs a little push to get it into the world of Xamarin Forms. 它需要一点点推动才能进入Xamarin Forms的世界。

Finally i got an answer of the Xamarin support. 最后我得到了Xamarin支持的答案。 The solution i was thinking about works. 解决方案我正在考虑工作。 In the PCL i just have the static Settings class which stores the different CultureInfo objects. 在PCL中,我只有static Settings class ,它存储不同的CultureInfo对象。 In addition I defined a method for changing the current culture and the language of the resources file. 另外,我定义了一种用于更改当前文化和资源文件语言的方法。

public static void ChangeCurrentCultureInfo(CultureInfo cultureInfo)
{
    CurrentCulture = cultureInfo;
    Resource.Culture = CurrentCulture;
}

It was important to set the default language in the App() constructor before I initialize the main page. 在初始化主页面之前,在App()构造函数中设置默认语言非常重要。 Now i got a listview with all supported languages with one tapped event which calls the ChangeCurrentCultureInfo method. 现在我得到了一个包含所有支持语言的列表视图,其中有一个调用事件调用ChangeCurrentCultureInfo方法。

Nevertheless i want to thank Andy Hopper for providing his solution! 不过我要感谢Andy Hopper提供他的解决方案!

Regards 问候

you can call setLocale method available in each platform projects from PCL using the interface ILocalize like this: 您可以使用ILocalize接口从PCL调用每个平台项目中的setLocale方法,如下所示:

CultureInfo ci=new CultureInfo("ar");
Xamarin.Forms.DependencyService.Get<ILocalize>().SetLocale(ci);                      

AppResources.Culture = ci;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM