如何找到绑定到属性的所有目标依赖属性?

发布于 2024-11-15 13:27:23 字数 227 浏览 2 评论 0原文

例如:

<UserControl>
    <TextBox Text="{Binding Path=Foo, Mode=TwoWays}"/>
    <TextBlock Text="{Binding Path=Foo}"/>
</UserControl>

在代码中,是否可以找到使用 Foo 属性作为源的依赖属性列表?

For example:

<UserControl>
    <TextBox Text="{Binding Path=Foo, Mode=TwoWays}"/>
    <TextBlock Text="{Binding Path=Foo}"/>
</UserControl>

In code, is it possible to find a list of dependency properties that uses the Foo property as the source?

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

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

发布评论

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

评论(2

千柳 2024-11-22 13:27:23

正如 HB 指出的那样,这实际上取决于情况,但即使在“简单”的情况下,它也会非常密集。

在您的示例中,假设您可以访问 Bindings,您可以检查 Path 属性并查看它是否引用您的“Foo”属性。但在某些情况下,这是行不通的。例如,像 {Binding Path=DataContext.Foo} 这样的绑定。路径可能比单个属性名称复杂得多。

此外,DataContext 可能会根据您所在的位置而发生变化。默认情况下,DataTemplate 中定义的元素不会继承其父级数据上下文。因此,如果您有:

<UserControl>
    <ContextControl Content="Test">
        <ContextControl.ContentTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Path=Foo, Mode=TwoWay}"/>
            </DataTemplate>
        </ContextControl.ContentTemplate>
    </ContextControl>
</UserControl>

那么 Foo 属性引用的是字符串 "Test" 而不是您的对象。还有一种情况是在 Binding 上使用 Source、ElementName 和relativeSource 属性。

假设您只有一个 DataContext 并且仅使用单个单词路径,那么您可能会找到大多数(如果不是全部)目标。

首先,您需要迭代视觉树和逻辑树中的每个元素VisualTreeHelper 遍历可视化树。逻辑树会更复杂。

对于每个元素,您必须迭代定义的每个依赖属性。为此,您必须使用对 DependencyProperty 类型的公共静态字段的反射。

接下来,对于每个依赖项属性,您必须调用 GetBindingExpression 获取关联的BindingExpression。然后,您可以使用 ParentBinding 属性。

然后比较路径属性就很简单了。

It depends really and, as H.B. points out, but it would be very intensive even in the "easy" cases.

In your example, assuming you can get at the Bindings, you can check the Path property and see if it references your "Foo" property. But there are cases, where that would not work. A binding like {Binding Path=DataContext.Foo} for example. Path's can be much more complex then single property names.

In addition, the DataContext can change depending on where you are. Elements defined in a DataTemplate do not inherit their parents data context by default. So if you had:

<UserControl>
    <ContextControl Content="Test">
        <ContextControl.ContentTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Path=Foo, Mode=TwoWay}"/>
            </DataTemplate>
        </ContextControl.ContentTemplate>
    </ContextControl>
</UserControl>

Then the Foo property refers to the the string "Test" not your object. There is also the case where the Source, ElementName, and RelativeSource properties are used on the Binding.

Assuming that you only have a single DataContext and only use single word paths, then you could probably find most, if not all, the targets.

First, you'd need to iterate over every element in the visual and logical trees VisualTreeHelper to traverse the visual tree. The logical tree would be tricker.

For each element, you'd have to iterate over every dependency property defined. For this you'd have to use reflection to the the public static fields of type DependencyProperty.

Next, for each dependency property you'd have to call GetBindingExpression to get the associated BindingExpression. Then you can get the parent binding using the ParentBinding property.

Then it's a simple matter of comparing the path property.

染火枫林 2024-11-22 13:27:23

是的,据我所知,您需要使用反射,而且就性能而言这也不是一个好主意。

Yes, and for all i know you need to use reflection and it is also not a good idea in terms of performance.

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