来自多个来源的绑定

发布于 2024-11-27 19:48:47 字数 545 浏览 1 评论 0原文

我的场景: 我有一个带有视图的 Silverlight 应用程序,我想将文本框绑定到一个对象(双向),并将所有标签绑定到保存标签翻译的字典。

我的方法是将页面的数据上下文设置为包含两个项目的字典,其中一个是对象,另一个是翻译字典。

在 xaml 中,代码如下所示:

<TextBlock Text="{Binding [dict].[name],FallbackValue='Fallback'}" />
<TextBox Text="{Binding [obj].name,Mode=TwoWay}" />

这最初是有效的,但是如果我更改数据上下文上的对象,则 xaml 不会收到有关任何更改的通知,并且不会更新。

我有一个使用转换器进行翻译的可行解决方案,但是由于一个转换器参数的限制,我不喜欢该解决方案。此外,无法在文本块中放置后备值,这导致在设计页面时出现“不可见”文本块。

关于如何解决这个问题有什么建议吗?它不必使用我的字典,如果我可以将数据上下文设置为对象(可以工作)并以某种不同的方式绑定标签,那也可以。

My scenario:
I've got a Silverlight Application with a View, where i want to bind the textboxes to an object (two-way) and all labels to a dictionary holding the label translations.

My approach was to set the datacontext of the page to a dictionary with two items, one of them is the object and the other is the translation-dictionary.

In xaml the code looks like the following:

<TextBlock Text="{Binding [dict].[name],FallbackValue='Fallback'}" />
<TextBox Text="{Binding [obj].name,Mode=TwoWay}" />

This works initially, if I however change the object on the datacontext, the xaml is not notified about any changes and doesn't update.

I've had a working solution using a Converter for the translations, however due to the limitations on one converterparameter I didn't like the solution. In addition it wasn't possible to place a fallback-value in the textblock, which resulted in "invisible" textblocks while designing the page.

Any suggestions on how to solve this issue? It doesn't have to be using my dictionary, it would be also okay if i could set the datacontext to the object (which works) and bind the labels somehow different.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

垂暮老矣 2024-12-04 19:48:47

我知道这会得到很多传统的答案,但我也想提出一些完全原创的东西,我们自己尝试(并成功)使用附加属性而不是绑定来更有效地本地化 Silverlight:

完成后的 Silverlight 项目本地化

I know this will get a lot of traditional answers, but I would also like to put forward something completely original we tried (and succeeded) doing ourselves for more efficient localisation of Silverlight using Attached Properties instead of binding:

Localisation of Silverlight projects after completion

百变从容 2024-12-04 19:48:47

最灵活的做法是,不要将视图的 DataContext 设置为字典,最好将 DataContext 设置为类似 ViewModel 的东西。也就是说,一个简单的类包含多个属性:一个用于您的“对象”,一个用于您的翻译词典。

然后让充当 ViewModel 的类实现 INotifyPropertyChanged。
在您的类中创建一个名为 OnPropertyChanged 的​​方法,该方法接受表示您的属性名称的字符串。在该方法中,引发传入 ViewModel 类实例的 PropertyChanged 事件和传入属性名称的新 PropertyChangedEventArgs。

回到您在 Set 中创建的属性(对象和字典),设置值后,调用 OnPropertyChanged 并传入该属性的字符串名称。这将通知 UI 该属性的值已更改,并且本质上会将控件重新绑定到该属性。

最后,将视图上控件的 Text 属性绑定到刚刚在 ViewModel 中创建的新属性。这应该确保视图上的控件保持最新。

What would be the most flexible is rather than setting the DataContext for the view to a dictionary, you would be better off having the DataContext be something like a ViewModel. That is, a simple class that holds multiple properties: one for your "object" and one for your translation dictionary.

Then have the class that acts as your ViewModel implement INotifyPropertyChanged.
Create a method in your class called OnPropertyChanged that takes in a string representing your property name. In that method raise the PropertyChanged event passing in the instance of the ViewModel class and a new PropertyChangedEventArgs passing in the property name.

Back in the properties you created (object and dictionary) in the Set, after setting the value, call OnPropertyChanged passing in the string name of that property. This will notify the UI that the value of this property has changed and will essentially rebind the control to that property.

Finally, bind the Text properties of your controls on your View to the new properties you just created in your ViewModel. That should ensure that the controls on the view stay up to date.

山田美奈子 2024-12-04 19:48:47

我找到了解决方案,但无法回答我自己的问题(8小时限制..)
我认为这正是 Hydroslide 建议的方法。


  1. 创建一个保存所有数据并实现 INotifyPropertyChanged 的​​类

    公共类 MyDatacontext
      实现 ComponentModel.INotifyPropertyChanged
    
    '特性
    私有 _obj 作为对象
    私有 _dict 作为字典(字符串,字符串)
    
    '活动
    公共事件 PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) 实现 System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    
    '方法
    公共属性 Obj 作为对象
      得到
        返回_obj
      结束获取
      Set(ByVal 值作为对象)
        _obj = 值
        '通知 xaml 有关更改的对象
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Obj"))
      结束组
    结束财产
    
    公共属性 Dict As Dictionary(Of String, String)
      得到
        返回_dict
      结束获取
      Set(ByVal 值作为字典(Of String, String))
        _dict = 值
        '通知 xaml 有关更改的翻译
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Dict"))
      结束组
    结束财产
    结束课程
    
  2. 在页面代码中定义一个私有变量

    私有 mycontext 作为新的 MyDatacontext
    
  3. 在页面的构造函数中,用所需的数据填充“mycontext”

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

    >
    
    
  5. 根据需要使用更新您的对象/字典

    mycontext.Obj = LoadNextObject()
    

I found a solution, but wasn't able to answer my own question (8h limit..)
I think this is just the approach Hydroslide suggested.


  1. Create a class which holds all data and implements 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. Define a private var in your page code

    Private mycontext As New MyDatacontext
    
  3. In the constructor of your page, fill your "mycontext" with the desired data

    mycontext.Dict = LoadDictionary()
    mycontext.Obj = LoadObject()
    Me.DataContext = mycontext
    
  4. Change your xaml to the following

    <TextBlock Text="{Binding Dict.[name],FallbackValue=MyFallback}" />
    <TextBox Text="{Binding Obj.name,Mode=TwoWay}" />
    
  5. Update your object/dictionary as you like using

    mycontext.Obj = LoadNextObject()
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文