【发布时间】:2014-01-10 18:07:07
【问题描述】:
我面临的问题在于使用RelativeSource 的绑定在应用绑定的元素更改其在可视树中的位置时不会更新其目标。
所以,如果有以下代码片段:
<Border Tag="Border1">
<TextBlock Text="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType=Border}}" />
</Border>
<Border Tag="Border2" />
然后尝试从第一个 Border 中删除 TextBlock 并将其添加到第二个将不会导致 TextBlock 更改其 Text 值。
我能想到的最简单的解决方法是重新创建所有使用 RelativeSource 并应用于元素子树的绑定(简单地调用 UpdateTarget 没有好处)。有谁知道如何做到这一点?
调用ClearBinding-SetBinding 很简单,但是如何找到所有需要重新创建的依赖属性呢?我找不到可靠地收集对象的所有依赖属性(包括附加的)的方法。
另一种理论上可能的方法是子类化BindingBase,因此它将跟踪到实际源路径中的Visual 元素。虽然我很确定有一些内部密封的东西阻止了这一点。
欢迎任何想法和替代解决方案。
【问题讨论】:
-
我很好奇你为什么要像这样开始在可视化树中移动元素。
-
Err,我正在构建 PropertyGrid 控件,其中属性的编辑器只创建一次,但它所在的容器可以由父
ItemsControl重新创建(在用户重新选择的情况下)一个东西)。目前编辑器是Control(与视图模型+对应的DataTemplate相反)。 Perharps,我可以改变它,但在这一点上它不会是一个容易的改变。 :( -
在我看来,在 WPF 中出于任何目的使用
Tag属性只不过是一种 HACK。与使用Tag属性相比,肯定有几种更好的机制,因此将某个 UI 元素与任何给定的数据(附加属性、DataBinding 等)关联起来。 -
这只是一个例子......
-
那么是的,如果您停下来想一想,在使用
VirtualizingItemsControl 时,将项目的数据保存在 ViewModel 或 Model 中成为需要。由于 UI 会动态地被销毁/重新创建/回收到不同的数据项,因此您不能相信它会保持数据的状态。因此你需要一个虚拟机。