Joh*_*ore 4 data-binding xamarin xamarin.forms
鉴于以下ViewModel ......
public class NameEntryViewModel
{
public NameEntryViewModel()
{
Branding = new Dictionary<string, string>();
Branding.Add("HeaderLabelText", "Welcome to the app");
}
public Dictionary<string, string> Branding { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
绑定到页面...
<?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="Monaco.Forms.Views.NameEntryPage">
<Label Text="{Binding Branding[HeaderLabelText]}" />
</ContentPage>
Run Code Online (Sandbox Code Playgroud)
当页面出现时,Label将获得文本"欢迎使用该应用程序".这非常有效,适合我们的计划,可以自定义和全球化我们的应用程序.然后在此示例中静态设置品牌字典,但在现实世界中,它由来自服务调用的数据初始化.
但是,如果用户想要将语言切换为西班牙语,我们需要将每个绑定标签更新为新值.重置品牌字典并用西班牙语翻译填充它很容易,但是我们如何强制控件从其绑定源中刷新?
我试图在这里避免双向数据绑定b/c我们不希望为控件的每个Text属性创建支持属性的代码开销.因此,我们绑定了价值字典.
回答
我接受了下面的答案,但我没有使用传统的财产制定者.相反,当用户想要切换不同的语言时,我们现在有一个集中处理程序,它重新填充我们的Dictionary,然后通知对Dictionary的更改.我们正在使用MVVMCross,但你可以翻译成标准表格......
public MvxCommand CultureCommand
{
get
{
return new MvxCommand(async () =>
{
_brandingService.ToggleCurrentCulture();
await ApplyBranding(); // <-- this call repopulates the Branding property
RaisePropertyChanged(() => Branding);
});
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ván 11
正如@BillReiss所提到的,你需要使用OnPropertyChanged事件从这个类继承NameEntryViewModel:
public class BaseViewModel : INotifyPropertyChanged
{
protected BaseViewModel ()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler (this, new PropertyChangedEventArgs (propertyName));
}
}
Run Code Online (Sandbox Code Playgroud)
并创建一个私有属性,您可以为您分配公共属性,如:
Dictionary<string, string> _branding = new Dictionary<string, string>();
public Dictionary<string, string> Branding
{
get
{
return _branding;
}
set
{
_branding = value;
OnPropertyChanged(nameof(Branding));
}
}
Run Code Online (Sandbox Code Playgroud)
每当你设置Branding属性时,它都会让View知道有些东西发生了变化!有时如果你在背线上这样做,你必须使用Device.BeginInvokeOnMainThread()