【问题标题】:Dynamic resx translation in Xamarin Forms using MVVM使用 MVVM 在 Xamarin 表单中进行动态 resx 翻译
【发布时间】:2020-03-20 14:34:06
【问题描述】:

我们有一个用Pages 编写的应用程序,没有模式,我想使用 MVVM 重新编写它。目前我们使用Picker 进行语言选择,当文化发生变化时,我们再次设置所有label.Text 控件,以便用新语言重新绘制它们。 我使用 MVVM 重新编写了相同的页面,现在 Picker 中的 SelectedItem 绑定到 Language 对象。在 SelectedItem 的设置器中,我还更改了我的 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?有没有什么干净的方法来做这样的事情,这似乎是一个基本的翻译需求......或者它不是应该完成的,尤其是在没有关闭视图/应用程序的情况下?

我发现使用 IMarkupExtensionthis thread on Xamarin forums 进行本地化的方法最终有效地重新创建了页面...

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

【问题讨论】:

    标签: xamarin xamarin.forms localization


    【解决方案1】:

    首先创建您的 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;
    }
    

    在 SettingsPage 中,使用选择器选择语言。

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

    SettingsPage 的视图模型。

    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

    【讨论】:

    • 能否请您告诉我,当您想对诸如“篮子里有 {0} 个苹果”这样的标签进行处理时如何使用此技术,appleCount。我看到人们使用 {Binding count, StringFormat={x.Static resx:res.applemessage}} 这样做,但这不适用于 LocalizedResource。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多