使用 MVVM 在 Xamarin Forms 中进行动态 resx 转换

Dynamic resx translation in Xamarin Forms using MVVM

我们有一个使用 Pages 编写但没有模式的应用程序,我想使用 MVVM 重新编写它。目前我们使用 Picker 进行语言选择,当文化发生变化时,我们会再次设置所有 label.Text 控件,以便用新语言重绘它们。 我使用 MVVM 重写了同一页面,现在 Picker 中的 SelectedItem 绑定到 Language 对象。在 SelectedItem 的 setter 中,我还更改了我的 resx (AppResources.Culture) 的文化,但绑定到它的 UI(例如 Text="{x:Static resources:AppResources.Title)没有改变语言。

我的完整代码 SelectedItem setter:

            SetProperty(ref selectedLanguage, value);
            AppResources.Culture = value.Culture;
            cultureManager.SetLocale(value.Culture);

我应该如何更新 UI 的所有 Text?有没有什么干净的方法可以做这样的事情,这似乎是一个基本的翻译需要......或者它不是要完成的,尤其是在不关闭 view/app 的情况下?

我找到的使用 IMarkupExtension and this thread on Xamarin forums 进行本地化的方法最终有效地重新创建了页面...

我的目标是理想地重新加载文本,而无需重新创建 view/close 应用程序,使用 MVVM 和干净的代码。我有大约 10 个视图,所以它必须是可重复使用的。

首先创建您的 RESX 资源。例如,我使用 en、nl、fr。

创建视图模型以绑定 LocalizedResources。

 public class ViewModelBase : INotifyPropertyChanged
{
    public LocalizedResources Resources
    {
        get;
        private set;
    }

    public ViewModelBase()
    {
        Resources = new LocalizedResources(typeof(LocalizationDemoResources), App.CurrentLanguage);
    }

    public void OnPropertyChanged([CallerMemberName]string property = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

在设置页面中,使用选择器选择语言。

   <StackLayout>
        <Label Text="{Binding Resources[PickLng]}" />
        <Picker ItemsSource="{Binding Languages}" SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}" />
    </StackLayout>

查看设置页面模型。

public class SettingsViewModel : ViewModelBase
{
    public List<string> Languages { get; set; } = new List<string>()
    {
        "EN",
        "NL",
        "FR"
    };

    private string _SelectedLanguage;

    public string SelectedLanguage
    {
        get { return _SelectedLanguage; }
        set
        {
            _SelectedLanguage = value;
            SetLanguage();
        }
    }

    public SettingsViewModel()
    {
        _SelectedLanguage = App.CurrentLanguage;
    }

    private void SetLanguage()
    {
        App.CurrentLanguage = SelectedLanguage;
        MessagingCenter.Send<object, CultureChangedMessage>(this,
                string.Empty, new CultureChangedMessage(SelectedLanguage));
    }
}

不要忘记绑定上下文。

我已经上传到GitHub,你可以从我GitHub的DynamicallyBindingRESXResources文件夹下载以供参考。

https://github.com/WendyZang/Test.git