从多个源绑定



我的场景:我有一个带有视图的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建议的方法。


  1. 创建一个类来保存所有的数据并实现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
    
  2. 在你的页面代码中定义一个私有变量

    Private mycontext As New MyDatacontext
    
  3. 在你的页面的构造函数中,用所需的数据填充你的"mycontext"

    mycontext.Dict = LoadDictionary()
    mycontext.Obj = LoadObject()
    Me.DataContext = mycontext
    
  4. 将您的xaml更改为以下

    <TextBlock Text="{Binding Dict.[name],FallbackValue=MyFallback}" />
    <TextBox Text="{Binding Obj.name,Mode=TwoWay}" />
    
  5. 使用

    更新对象/字典
    mycontext.Obj = LoadNextObject()
    

最新更新