xamarin.forms: 在运行时更改语言不会影响 UI 你好

xamarin.forms: Changing language at runtim doesnt affect UI Hi

我有一个应用程序,用户可以在其中选择他或她的语言:

我有两个资源文件,它们都可以工作,因为我可以看到显示在 Xaml 中的文本。

简短概述:

英语资源:

 <data name="Next" xml:space="preserve">
    <value>next</value>
    </data>

    <data name="German" xml:space="preserve">
    <value>German</value>
    </data>

    <data name="Arabic" xml:space="preserve">
    <value>Arabic</value>
    </data>

标签:

<Label Text="{x:Static resources:AppResources.German}"
                       VerticalOptions="Center"
                       Grid.Row="0"/>
                <Label Text="{x:Static resources:AppResources.Arabic}"
                       VerticalOptions="Center"
                       Grid.Row="1"/>
                <Label Text="{x:Static resources:AppResources.English}"
                       VerticalOptions="Center"
                       Grid.Row="2"/>

我知道它们可以工作,因为当我从一个模拟器切换到另一个(一个在德国,一个在英国)时,语言会自动改变。

但我希望用户能够在单击按钮时更改语言。

我试过了:

 case "english":
                    CultureInfo culture = new CultureInfo("en-US");
                    CultureInfo.DefaultThreadCurrentCulture = culture;
                    mainPage.FlowDirection = FlowDirection.LeftToRight;
                    break;

但是 phone 只是忽略了语言变化。

知道为什么吗?

您可以创建一个 LocalizationResourceManager class 来处理语言更改,并且还会有一个带有翻译的 属性。当语言更改时,它会使该字符串无效,因此它将强制 属性 更改。

 public class LocalizationResourceManager : INotifyPropertyChanged
    {
        public static LocalizationResourceManager Instance { get; } = new LocalizationResourceManager();

        public string this[string text]
        {
            get
            {
                return AppResources.ResourceManager.GetString(text, AppResources.Culture);
            }
        }

        public void SetCulture(CultureInfo language)
        {
            Thread.CurrentThread.CurrentUICulture = language;
            AppResources.Culture = language;

            Invalidate();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void Invalidate()
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
        }
    }

不是将我们的字符串直接绑定到 AppResources class,而是使用 returns 和 BindingProperty 的翻译扩展并绑定到我们的新 LocalizationResourceManager.

[ContentProperty("Text")]
public class TranslateExtension : IMarkupExtension<BindingBase>
{
    public string Text { get; set; }
    public string StringFormat { get; set; }
    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
    {
        return ProvideValue(serviceProvider);
    }

    public BindingBase ProvideValue(IServiceProvider serviceProvider)
    {
        var binding = new Binding
        {
            Mode = BindingMode.OneWay,
            Path = $"[{Text}]",
            Source = LocalizationResourceManager.Instance,
            StringFormat= StringFormat

        };
        return binding;
    }
}

用法:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MultilingualXFSample.Views.ChangeLanguagePage"
             xmlns:helpers="clr-namespace:MultilingualXFSample.Helpers">

         <Label  Text="{helpers:Translate SelectLanguage}" />
</ContentPage>

更多可以查看:Mastering Multilingual in Xamarin.Forms

这里有一个示例:https://github.com/CrossGeeks/MasteringMultilingualSample .