【问题标题】:Why cannot binding find the target?为什么绑定找不到目标?
【发布时间】:2021-04-24 14:08:40
【问题描述】:

我正在 WPF 中设计一个控件,其中包含一个非常常见的模式:按钮打开下拉菜单。 XAML 的相关部分如下所示:

<ToggleButton x:Name="btnFilterPopup" IsChecked="{Binding IsOpen, ElementName=filterPopup, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}" Margin="{StaticResource DialogItemsExceptLeftMargin}" FontFamily="Marlett" Content="6"/>
<Popup x:Name="filterPopup" PlacementTarget="{Binding ElementName=btnFilterPopup}" Placement="Bottom">
   <Border Background="{StaticResource ToolPopupBackgroundBrush}">
      <StackPanel Orientation="Vertical" Margin="{StaticResource DialogItemsMargin}">
         <CheckBox IsChecked="{Binding FilterCaseSensitive, Mode=TwoWay}" Margin="{StaticResource DialogItemsMargin}">Case sensitive</CheckBox>
         <CheckBox IsChecked="{Binding FilterExcludes, Mode=TwoWay}" Margin="{StaticResource DialogItemsExceptTopMargin}">Exclude matching</CheckBox>
      </StackPanel>
   </Border>
</Popup>

但是,两个绑定都找不到它的目标。诊断如下所示:

System.Windows.Data Warning: 67 : BindingExpression (hash=46479497): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=46479497): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 :     Lookup name filterPopup:  queried ToggleButton (hash=36168141)
System.Windows.Data Warning: 67 : BindingExpression (hash=46479497): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=46479497): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 :     Lookup name filterPopup:  queried ToggleButton (hash=36168141)
System.Windows.Data Warning: 67 : BindingExpression (hash=46479497): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=46479497): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 :     Lookup name filterPopup:  queried ToggleButton (hash=36168141)
System.Windows.Data Warning: 67 : BindingExpression (hash=46479497): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=46479497): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 :     Lookup name filterPopup:  queried ToggleButton (hash=36168141)
System.Windows.Data Warning: 67 : BindingExpression (hash=46479497): Resolving source  (last chance)
System.Windows.Data Warning: 70 : BindingExpression (hash=46479497): Found data context element: <null> (OK)
System.Windows.Data Warning: 74 :     Lookup name filterPopup:  queried ToggleButton (hash=36168141)
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=filterPopup'. BindingExpression:Path=IsOpen; DataItem=null; target element is 'ToggleButton' (Name='btnFilterPopup'); target property is 'IsChecked' (type 'Nullable`1')
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=btnFilterPopup'. BindingExpression:(no path); DataItem=null; target element is 'Popup' (Name='filterPopup'); target property is 'PlacementTarget' (type 'UIElement')

为什么绑定找不到他们的TargetElements?

【问题讨论】:

  • 我无法重现该问题,对我而言,使用您的代码似乎一切正常:弹出窗口位于按钮下方,复选框更改属性。您是否为您的窗口设置了DataContext?请参考minimal reproducible example
  • 也许您正在某处更改DataContext?在PopupToggleButton 的父容器中?
  • @Sinatr 查看我对 Lennart 答案的评论,为了方便起见,我将在此重复一遍:令人惊讶的是,当我将这两个控件直接剪切并粘贴到主窗口时,它们工作正常。它们被放置在嵌入在 TabControl 中的 UserControl 中(手动,如

标签: c# wpf xaml data-binding


【解决方案1】:

某些控件(例如 Popups)不是可视化树的一部分,因此无法通过这种绑定访问。在您的情况下,我会将 IsOpen 属性绑定到您的 VM 中的一个属性,并将其用于 IsChecked 绑定。 PlacementTarget 绑定也是如此,如果您不想或无法在后面的代码中显式设置它。

【讨论】:

  • 最初两个绑定都在 Popup 内,所以它试图访问按钮,但也不能...(我的意思是:IsOpen="{Binding ...}"
  • @Spook 您可能还需要在 Popup 上设置 DataContext
  • 令人惊讶的是,当我将这两个控件直接剪切并粘贴到主窗口时,它们工作正常。它们被放置在嵌入在 TabControl 中的 UserControl 中(手动,如 &lt;TabItem&gt;&lt;controls:MyControl /&gt;&lt;/TabItem&gt;
  • 在您的回答中,您可能指的是relative source binding in popup 错误。否则我看不到视觉树在这里是如何相关的。 DataContext 是继承的,设置PlacementTarget 似乎也可以。
【解决方案2】:

Popup 与放置目标不属于同一可视树。您可以使用RelativeSource 绑定到Popup 本身,以访问对应PlacementTargetDataContext

<ToggleButton x:Name="btnFilterPopup" IsChecked="{Binding IsOpen, ElementName=filterPopup, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}" Margin="{StaticResource DialogItemsExceptLeftMargin}" FontFamily="Marlett" Content="6"/>
<Popup x:Name="filterPopup" PlacementTarget="{Binding ElementName=btnFilterPopup}" Placement="Bottom">
   <Border Background="{StaticResource ToolPopupBackgroundBrush}">
      <StackPanel Orientation="Vertical" Margin="{StaticResource DialogItemsMargin}">
         <CheckBox IsChecked="{Binding PlacementTarget.DataContext.FilterCaseSensitive, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type Popup}}}" Margin="{StaticResource DialogItemsMargin}">Case sensitive</CheckBox>
         <CheckBox IsChecked="{Binding PlacementTarget.DataContext.FilterExcludes, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type Popup}}}">Exclude matching</CheckBox>
      </StackPanel>
   </Border>
</Popup>

或者,将PopupDataContext 设置为引用其PlacementTarget

<ToggleButton x:Name="btnFilterPopup" IsChecked="{Binding IsOpen, ElementName=filterPopup, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}" Margin="{StaticResource DialogItemsExceptLeftMargin}" FontFamily="Marlett" Content="6" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"/>
<Popup x:Name="filterPopup" PlacementTarget="{Binding ElementName=btnFilterPopup}" Placement="Bottom">
   <Border Background="{StaticResource ToolPopupBackgroundBrush}">
      <StackPanel Orientation="Vertical" Margin="{StaticResource DialogItemsMargin}">
         <CheckBox IsChecked="{Binding FilterCaseSensitive, Mode=TwoWay}" Margin="{StaticResource DialogItemsMargin}">Case sensitive</CheckBox>
         <CheckBox IsChecked="{Binding FilterExcludes, Mode=TwoWay}" Margin="{StaticResource DialogItemsExceptTopMargin}">Exclude matching</CheckBox>
      </StackPanel>
   </Border>
</Popup>

【讨论】:

  • 最后我只是从后面的代码中手动配置了绑定。有趣的是,如果您将我的代码直接复制“粘贴”到窗口,它就可以工作。但放在 DataTemplate 机制显示的 UserControl 中,却没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2019-03-13
相关资源
最近更新 更多