我的场景:我有一个带有视图的Silverlight应用程序,我想将文本框绑定到一个对象(双向),并将所有标签绑定到保存标签翻译的字典。
我的方法是将页面的数据上下文设置为包含两个条目的字典,其中一个是对象,另一个是翻译字典。
在xaml中,代码如下所示:<TextBlock Text="{Binding [dict].[name],FallbackValue='Fallback'}" />
<TextBox Text="{Binding [obj].name,Mode=TwoWay}" />
这最初是有效的,但是如果我在数据上下文中更改了对象,xaml不会收到任何更改的通知,也不会更新。
我有一个使用转换器进行翻译的工作解决方案,但是由于一个转换器参数的限制,我不喜欢这个解决方案。此外,不能在文本块中放置回退值,这导致在设计页面时出现"不可见"的文本块。
对于如何解决这个问题有什么建议吗?它不一定要使用我的字典,如果我可以将数据上下文设置为对象(这是有效的)并以某种方式绑定标签,也可以。我知道这将得到很多传统的答案,但我也想提出一些完全原创的东西,我们自己尝试(并成功)使用附加属性而不是绑定来更有效地本地化Silverlight:
Silverlight项目完成后的本地化
最灵活的方法是将视图的DataContext设置为字典,而不是将DataContext设置为ViewModel之类的东西。也就是说,一个拥有多个属性的简单类:一个用于"对象",另一个用于翻译字典。
然后让作为ViewModel的类实现INotifyPropertyChanged。在你的类中创建一个名为OnPropertyChanged的方法,它接受一个表示属性名称的字符串。在该方法中,引发在ViewModel类的实例中传递的PropertyChanged事件和传入属性名的新的PropertyChangedEventArgs。
回到你在Set中创建的属性(对象和字典),在设置值之后,调用OnPropertyChanged传递该属性的字符串名称。这将通知UI该属性的值已经更改,并将控件重新绑定到该属性。
最后,将视图上控件的Text属性绑定到刚刚在ViewModel中创建的新属性。这将确保视图上的控件保持最新
我找到了一个解决方案,但无法回答我自己的问题(8h限制…)我认为这正是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()