我的情景: 我有一个带有View的Silverlight应用程序,我希望将文本框绑定到一个对象(双向),将所有标签绑定到一个包含标签翻译的字典。
我的方法是将页面的datacontext设置为包含两个项目的字典,其中一个是对象,另一个是翻译字典。
在xaml中,代码如下所示:
<TextBlock Text="{Binding [dict].[name],FallbackValue='Fallback'}" />
<TextBox Text="{Binding [obj].name,Mode=TwoWay}" />
这最初起作用,但是如果我更改了datacontext上的对象,则不会通知xaml任何更改并且不会更新。
我有一个使用Converter进行翻译的工作解决方案,但是由于一个转换器参数的限制,我不喜欢这个解决方案。此外,无法在文本块中放置一个回退值,这会在设计页面时产生“不可见”的文本块。
有关如何解决此问题的任何建议?它不必使用我的字典,如果我可以将datacontext设置为对象(可以工作)并以不同的方式绑定标签,那也没关系。
答案 0 :(得分:1)
我知道这会得到很多传统的答案,但我还想提出一些完全原创的东西,我们尝试(并成功)使用附加属性而不是绑定来更有效地本地化Silverlight:
答案 1 :(得分:1)
最灵活的不是将视图的DataContext设置为字典,最好让DataContext像ViewModel一样。也就是说,一个包含多个属性的简单类:一个用于“对象”,另一个用于翻译字典。
然后让充当ViewModel的类实现INotifyPropertyChanged。 在类中创建一个名为OnPropertyChanged的方法,该方法接受表示属性名称的字符串。在该方法中,引发传递ViewModel类实例的PropertyChanged事件和传入属性名称的新PropertyChangedEventArgs。
返回Set中创建的属性(对象和字典),设置值后,调用OnPropertyChanged传入该属性的字符串名称。这将通知UI该属性的值已更改,并且基本上将控件重新绑定到该属性。
最后,将View上控件的Text属性绑定到刚刚在ViewModel中创建的新属性。这应该确保视图上的控件保持最新。
答案 2 :(得分:1)
我找到了一个解决方案,但无法回答我自己的问题(8小时限制......) 我认为这只是Hydroslide建议的方法。
创建一个包含所有数据并实现INotifyPropertyChanged
的类Public Class MyDatacontext
Implements ComponentModel.INotifyPropertyChanged
'Properties
Private _obj As Object
Private _dict As Dictionary(Of String, String)
'Events
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
'Methods
Public Property Obj As Object
Get
Return _obj
End Get
Set(ByVal value As Object)
_obj = value
'Notify the xaml about the changed Object
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Obj"))
End Set
End Property
Public Property Dict As Dictionary(Of String, String)
Get
Return _dict
End Get
Set(ByVal value As Dictionary(Of String, String))
_dict = value
'Notify the xaml about the changed translation
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Dict"))
End Set
End Property
End Class
在页面代码中定义私有变量
Private mycontext As New MyDatacontext
在页面的构造函数中,使用所需数据填充“mycontext”
mycontext.Dict = LoadDictionary()
mycontext.Obj = LoadObject()
Me.DataContext = mycontext
将您的xaml更改为以下
<TextBlock Text="{Binding Dict.[name],FallbackValue=MyFallback}" />
<TextBox Text="{Binding Obj.name,Mode=TwoWay}" />
使用
更新您的对象/词典mycontext.Obj = LoadNextObject()