为什么绑定找不到目标?
Why cannot binding find the target?
我正在 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')
为什么绑定找不到它们的 TargetElement
?
弹出窗口等某些控件不是可视化树的一部分,因此无法通过那种绑定访问。在您的情况下,我会将 IsOpen 属性 绑定到您的 VM 中的 属性 并将其用于 IsChecked 绑定。对于 PlacementTarget 绑定也是如此,如果您不想或不能在代码隐藏中明确设置它。
A Popup
与放置目标不属于同一可视化树。您可以使用 RelativeSource
绑定到 Popup
本身,以访问相应 PlacementTarget
.
的 DataContext
<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>
或者,设置 Popup
的 DataContext
参考其 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>
我正在 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')
为什么绑定找不到它们的 TargetElement
?
弹出窗口等某些控件不是可视化树的一部分,因此无法通过那种绑定访问。在您的情况下,我会将 IsOpen 属性 绑定到您的 VM 中的 属性 并将其用于 IsChecked 绑定。对于 PlacementTarget 绑定也是如此,如果您不想或不能在代码隐藏中明确设置它。
A Popup
与放置目标不属于同一可视化树。您可以使用 RelativeSource
绑定到 Popup
本身,以访问相应 PlacementTarget
.
DataContext
<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>
或者,设置 Popup
的 DataContext
参考其 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>