【问题标题】:What's the difference between these two ways of declaring a self binding?这两种声明自绑定的方式有什么区别?
【发布时间】:2012-11-14 12:00:01
【问题描述】:

我有一个包含 ItemsSource DependenceProperty 的 UserControl,它必须绑定到内部控件的 ItemsSource 属性:

ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource Self}}"

ItemsSource="{Binding ItemsSource, ElementName=controlName}"

controlName 是控件的名称。

第一个绑定不工作,而第二个工作。我不明白其中的区别。

有什么想法吗?

编辑:

XAML:

<UserControl x:Class="MultiSelectTreeView.MultiSelectableTreeView"

         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

         mc:Ignorable="d"

         Name="multiTree" >

This does not work ---> <TreeView ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource Self}}" >
This works ---> <TreeView ItemsSource="{Binding ItemsSource, ElementName=multiTree}" >

【问题讨论】:

  • 'controlName` 是您的 UserControl 的名称吗?
  • 更新了答案。你可以试试吗?

标签: c# .net wpf binding


【解决方案1】:

如果你想绑定到父 UserControl 的 DP,你需要使用Mode = FindAncestor 绑定它。由于您对内部控制具有约束力,因此您需要沿着可视化树向上移动。

Self Mode 将在内部控件而不是父 UserControl 中搜索 DP。

ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, 
                                                   AncestorType=UserControl}}"

【讨论】:

  • 现在我明白了,Self 指的是 TreeView 本身,而不是它的父级。
【解决方案2】:

我从您的问题中假设您的 Xaml 在结构上是这样的:

<UserControl x:Name="rootElement">
    <ListBox ItemsSource="{Binding .....}" />
</UserControl>

然后您的绑定将执行以下操作:

ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource Self}}"

...这将在声明绑定的控件(即ListBox)上查找属性ItemsSource。在您的情况下,这将导致一个问题,因为您实际上是在设置无限递归:您的 ItemsSource 绑定到 ItemsSource 绑定到...无限期。您提到您在此处使用 UserControl,我怀疑您可能期望 RelativeSource 返回根 UserControl 元素 - 但事实并非如此。

ItemsSource="{Binding ItemsSource, ElementName=rootElement}"

...这将绑定到具有特定名称的控件上的属性ItemsSource。如果您在UserControl 中工作,那么通常您会在UserControl 的根元素上设置x:Name,并以这种方式从绑定中引用它。这将允许您将子 ListBox 绑定到您的 UserControl 的公共 ItemsSource 属性。

仅供参考,另一种选择是使用AncestorType 绑定来查找您的父级UserControl。如果你的 UserControl 类型被称为 MyControl,它看起来像这样:

ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource FindAncestor, AncestorType=MyControl}}"

【讨论】:

  • 谢谢,我遇到的问题是,当我使用 Self 时,我认为 Self 是容器控件,而不是设置绑定的控件。感谢您的帮助。
猜你喜欢
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 2012-04-01
相关资源
最近更新 更多