代码之家  ›  专栏  ›  技术社区  ›  Bryan Anderson

如何实现“传递”数据绑定?

  •  0
  • Bryan Anderson  · 技术社区  · 16 年前

    一点背景: 我正在从存储在属性表(控件类型、标签、页边距等)中的数据库加载WPF UI,这些属性表被加载到我称为ControlPresenter的类中。基本上,我将ControlPresenter设置为ContentPresenter的DataContext,并使用TemplateSelector选择要加载的控件类型。数据模板从ControlPresenter公开的DependencyProperties中加载其属性。

    这一切都非常有效。我遇到的问题是,当我尝试将其他演示者(具有实现inotifyPropertiesChanged的常规属性)中的数据(例如,文本框的文本属性绑定到演示者的名称属性)绑定到这些控件时。控件的DataContext是关联的ControlPresenter,因此我无法直接绑定到其他Presenter,也无法在同一依赖属性上设置两个绑定(我无法将控件和所需Presenter属性绑定到同一个DP)。

    可能的解决方案:

    1. 我可以将所有其他演示者转换为使用DPS(非常耗时,并且容易导致继承问题)
    2. 对于要传递的每个属性,我可以使用两个dps,并尝试通过更改的通知将它们联系在一起。

    这两个看起来都有问题,而且很容易破裂,所以我希望有人能想出更好的解决方案。

    编辑: 我想出了一个相当有效的解决方案(见下文)。感谢所有看过这个的人,如果你能想出比我更好的方法,请告诉我。

    2 回复  |  直到 15 年前
        1
  •  0
  •   markti    16 年前

    有几种方法可以访问超出范围的数据上下文。

    1)elementname绑定

    这可能是最不有用的,因为在大多数现实场景中,您尝试绑定的内容都超出了名称范围。但这是一种访问并行或父数据上下文的方法,只要框架元素在名称范围内。

    <TextBox Text="{Binding ElementName=ControlSomewhereElseBoundToSomeOtherControlPresenter, Path=DataContext.SomeTextPropertyOnTheControlPresenter}" />
    

    2)相对资源绑定

    这类似于1,但使用relativesource导航到适当的可视元素并获取数据上下文。当然,这假定您尝试获取的数据上下文位于您当前在可视化树中的位置之上。

    3)使用静态继电器

    您可以在作为ViewModel外观的静态类中公开替代的ControlPresenter。然后,在每个ViewModel中构造传递给静态方法/属性的实例属性。这是跨多个视图模型实现共享存储的常用方法。我知道这种技术需要您稍微改变一下您的模式,但是在这些“ControlPresenter”类周围添加一个简单的ViewModel包装器似乎比您描述的选项要简单得多。

        2
  •  0
  •   Bryan Anderson    16 年前

    我最终在代码中设置了绑定,方法是将binding.source设置为所需的ViewModel,然后在数据库中使用binding.path的路径。我将绑定存储在一个字典(DependencyProperty,bindingBase)中,当控件加载时,我使用bindingOperations.setbinding设置控件上的绑定。除了偶尔出现的操作顺序问题(例如,如果在itemssource之前设置了selectedItem/selectedValue,则会设置该项,但不会显示在组合框中),这似乎非常有效。