C# 为什么绑定找不到目标?

C# 为什么绑定找不到目标?,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,我正在WPF中设计一个控件,它包含一个非常常见的模式:按钮打开下拉菜单。XAML的相关部分如下所示: System.Windows.Data Warning: 67 : BindingExpression (hash=46479497): Resolving source System.Windows.Data Warning: 70 : BindingExpression (hash=46479497): Found data context element: <null> (O

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

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')

区分大小写
排除匹配
但是,这两个绑定都找不到其目标。诊断如下所示:

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')
System.Windows.Data警告:67:BindingExpression(hash=46479497):解析源
System.Windows.Data警告:70:BindingExpression(哈希=46479497):找到数据上下文元素:(确定)
System.Windows.Data警告:74:查找名称过滤器POUP:查询的切换按钮(哈希=36168141)
System.Windows.Data警告:67:BindingExpression(哈希=46479497):正在解析源
System.Windows.Data警告:70:BindingExpression(哈希=46479497):找到数据上下文元素:(确定)
System.Windows.Data警告:74:查找名称过滤器POUP:查询的切换按钮(哈希=36168141)
System.Windows.Data警告:67:BindingExpression(哈希=46479497):正在解析源
System.Windows.Data警告:70:BindingExpression(哈希=46479497):找到数据上下文元素:(确定)
System.Windows.Data警告:74:查找名称过滤器POUP:查询的切换按钮(哈希=36168141)
System.Windows.Data警告:67:BindingExpression(哈希=46479497):正在解析源
System.Windows.Data警告:70:BindingExpression(哈希=46479497):找到数据上下文元素:(确定)
System.Windows.Data警告:74:查找名称过滤器POUP:查询的切换按钮(哈希=36168141)
System.Windows.Data警告:67:BindingExpression(哈希=46479497):解析源(最后一次机会)
System.Windows.Data警告:70:BindingExpression(哈希=46479497):找到数据上下文元素:(确定)
System.Windows.Data警告:74:查找名称过滤器POUP:查询的切换按钮(哈希=36168141)
System.Windows.Data错误:4:找不到引用为“ElementName=filterPopup”的绑定源。BindingExpression:Path=IsOpen;DataItem=null;目标元素是“ToggleButton”(Name='btnFilterPopup');目标属性为'IsChecked'(类型'Nullable'1')
System.Windows.Data错误:4:找不到引用为“ElementName=btnFilterPopup”的绑定源。BindingExpression:(无路径);DataItem=null;目标元素是“Popup”(Name='filterPopup');目标属性为“PlacementTarget”(类型为“UIElement”)

为什么绑定找不到它们的
TargetElement
s?

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

某些控件(如弹出窗口)不是可视化树的一部分,因此无法通过这种绑定访问。在您的情况下,我会将IsOpen属性绑定到VM中的一个属性,并将其用于IsChecked绑定。如果您不想或无法在代码隐藏中显式设置PlacementTarget绑定,则与此相同。

A
弹出窗口
与placement目标不在同一可视树中。您可以使用
相对资源
绑定到
弹出窗口
本身,以访问相应
位置目标的
数据上下文

<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>
<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>

弹出窗口
与放置目标不在同一可视树中。您可以使用
相对资源
绑定到
弹出窗口
本身,以访问相应
位置目标的
数据上下文

<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>
<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>

最初,这两个绑定都在弹出窗口中,所以它试图到达按钮,但也不能。。。(我的意思是:
IsOpen=“{Binding…}”
)@Spook您可能还需要在弹出窗口上设置DataContext。令人惊讶的是,当我将这两个控件直接剪切并粘贴到主窗口时,它们工作正常。它们被放置在嵌入TabControl的UserControl中(手动,如
),在您的答案中,您可能指的是错误。否则,我看不出可视化树在这里有多重要。DataContext是继承的,设置
PlacementTarget
似乎也可以。最初两个绑定都在弹出窗口中,因此它试图到达按钮,但也无法。。。(我的意思是:
IsOpen=“{Binding…}”
)@Spook您可能还需要在弹出窗口上设置DataContext。令人惊讶的是,当我将这两个控件直接剪切并粘贴到主窗口时,它们工作正常。它们被放置在嵌入TabControl的UserControl中(手动,如
),在您的答案中,您可能指的是错误。否则,我看不出可视化树在这里有多重要。DataContext是继承的,设置
PlacementTarget
似乎也可以。我无法重现这个问题,对我来说,使用您的代码一切都正常:弹出窗口在按钮下方,复选框更改属性。您是否为窗口设置了
DataContext
?请参阅。可能您正在某个地方更改
DataContext
?在
弹出窗口
切换按钮
?@Sinatr的父容器中,请看我对Lennart答案的评论,为了方便起见,我将在这里重复:令人惊讶的是,当我将这两个控件直接剪切并粘贴到主窗口时,它们工作正常。它们被放置在一个内嵌在TabControl中的UserControl中(手动,比如)我无法重现这个问题,对我来说,使用您的代码一切都正常:弹出窗口在按钮下,复选框更改属性。您是否为窗口设置了
DataContext
?请参阅。可能您正在某个地方更改
DataContext
?在
弹出窗口
切换按钮
?@Sinatr的父容器中,请看我对Lennart答案的评论,为了方便起见,我将在这里重复:令人惊讶的是,当我将这两个控件直接剪切并粘贴到主窗口时,它们工作正常。它们被放置在嵌入TabCo的UserControl中