使用MVVM在Xamarin表单中进行动态resx翻译

使用MVVM在Xamarin表单中进行动态resx翻译,xamarin,xamarin.forms,localization,Xamarin,Xamarin.forms,Localization,我们有一个用页面编写的应用程序,没有模式,我想用MVVM重新编写它。目前,我们使用选择器进行语言选择,当区域性发生变化时,我们再次设置所有标签.文本控件,以便用新语言重新绘制它们。 我使用MVVM重新编写了相同的页面,现在选择器中的SelectedItem绑定到语言对象。在SelectedItem的setter中,我还更改了我的resx的区域性(AppResources.culture),但绑定到它的UI(例如Text=“{x:Static resources:AppResources.Titl

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

   <StackLayout>
        <Label Text="{Binding Resources[PickLng]}" />
        <Picker ItemsSource="{Binding Languages}" SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}" />
    </StackLayout>
my
SelectedItem
setter中的完整代码:

            SetProperty(ref selectedLanguage, value);
            AppResources.Culture = value.Culture;
            cultureManager.SetLocale(value.Culture);
我应该如何更新我的UI的所有
文本
?是否有任何干净的方法来做类似的事情,这似乎是一个基本的翻译需要…或者这是不应该做的,尤其是在不关闭视图/应用程序的情况下

我找到的本地化方法使用,并最终有效地重新创建页面


我的目标是理想地重新加载文本,而不必使用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));
    }
}
公共类设置viewmodel:ViewModelBase
{
公共列表语言{get;set;}=new List()
{
“嗯”,
“NL”,
“FR”
};
私有字符串\u选择的语言;
公共字符串选择语言
{
获取{return\u SelectedLanguage;}
设置
{
_SelectedLanguage=值;
SetLanguage();
}
}
公共设置视图模型()
{
_SelectedLanguage=App.CurrentLanguage;
}
私有void SetLanguage()
{
App.CurrentLanguage=所选语言;
MessagingCenter.发送(此,
空,新的CultureChangedMessage(SelectedLanguage));
}
}
不要忘记绑定上下文

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


首先创建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));
    }
}
公共类设置viewmodel:ViewModelBase
{
公共列表语言{get;set;}=new List()
{
“嗯”,
“NL”,
“FR”
};
私有字符串\u选择的语言;
公共字符串选择语言
{
获取{return\u SelectedLanguage;}
设置
{
_SelectedLanguage=值;
SetLanguage();
}
}
公共设置视图模型()
{
_SelectedLanguage=App.CurrentLanguage;
}
私有void SetLanguage()
{
App.CurrentLanguage=所选语言;
MessagingCenter.发送(此,
空,新的CultureChangedMessage(SelectedLanguage));
}
}
不要忘记绑定上下文

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


当你想处理这样的标签时,你能告诉我如何使用这种技术吗?“篮子里有{0}个苹果”,appleCount。我看到人们用
{Binding count,StringFormat={x.Static resx:res.applemessage}这样做
但是这对LocalizedResource不起作用。当你想处理这样的标签:“篮子里有{0}个苹果”,appleCount。我看到人们用
{Binding count,StringFormat={x.Static resx:res.applemessage}来做这件事时,你能告诉我这项技术是如何使用的吗
但这不适用于LocalizedResource。