情况如下:
<DataTemplate x:Key="ItemTemplate"
DataType="local:RoutedCustomCommand">
<Button Command="{Binding}"
Content="{Binding Text}"
ToolTip="{Binding Description}">
<Button.Visibility>
<MultiBinding Converter="{StaticResource SomeConverter}">
<!-- Converter simply checks flags matching
and returns corresponding Visibility -->
<Binding Path="VisibilityModes" />
<!-- VisibilityModes is a property of local:RoutedCustomCommand -->
<Binding Path="CurrentMode"
RelativeSource="{RelativeSource AncestorType=local:CustomControl}" />
<!-- CurrentMode is a property of local:CustomControl -->
</MultiBinding>
<Button.Visibility>
</Button>
</DataTemplate>
<local:CustomControl>
<!-- ... -->
<ToolBar ...
Width="15"
ItemTemplate={StaticResource ItemTemplate}
... />
<!-- Take a look at Width - it's especially is set to such a value
which forces items placement inside adorner overflow panel -->
<!-- If you change ToolBar to ItemsControl, items won't be wrapped by adorner
panel and everything will be OK -->
<!-- ... -->
</local:CustomControl>
一句话:当某个元素在装饰器中时,不能简单地使用 Binding 的 RelativeSource 属性来访问装饰器可视化树中的元素。
当我需要将其 FontSize 绑定到工具提示的所有者 FontSize 时,我已经习惯使用 ToolTip 遇到同样的问题 - 有非常方便的 PlacementTarget 属性,我不需要在树内查找 - 绑定看起来像这样:<Binding PlacementTarget.FontSize />
这是几乎相同的问题 - 当项目在 ToolBarOverflowPanel 内时,它似乎在装饰器内,因此 RelativeSource 显然无法绑定。
问题是:我该如何解决这个棘手的问题?我真的需要绑定到容器的属性。即使我能够绑定到装饰元素,也距离祖先还有很长的路要走。
UPD:最不幸的副作用是命令没有达到预期的目标 - 通过冒泡机制的命令传播在装饰者的视觉根处停止:(。明确目标的规范遇到同样的问题 - 目标必须在local:CustomControl
视觉树内,无法通过相同的 RelativeSource 绑定来访问。
UPD2:添加视觉和逻辑树遍历结果:
UPD3:删除了旧的遍历结果。添加了更精确的遍历:
UPD4:(希望这是最终版本)。遍历逻辑父级的可视化树:
VisualTree
System.Windows.Controls.Button
System.Windows.Controls.ContentPresenter
System.Windows.Controls.Primitives.ToolBarOverflowPanel inherits from System.Windows.Controls.Panel
LogicalTree
System.Windows.Controls.Border
Microsoft.Windows.Themes.SystemDropShadowChrome inherits from System.Windows.Controls.Decorator
System.Windows.Controls.Primitives.Popup
System.Windows.Controls.Grid
logical root: System.Windows.Controls.Grid
System.Windows.Controls.Border
LogicalTree
Microsoft.Windows.Themes.SystemDropShadowChrome inherits from System.Windows.Controls.Decorator
System.Windows.Controls.Primitives.Popup
System.Windows.Controls.Grid
logical root: System.Windows.Controls.Grid
Microsoft.Windows.Themes.SystemDropShadowChrome inherits from System.Windows.Controls.Decorator
LogicalTree
System.Windows.Controls.Primitives.Popup
System.Windows.Controls.Grid
logical root: System.Windows.Controls.Grid
System.Windows.Documents.NonLogicalAdornerDecorator inherits from System.Windows.Documents.AdornerDecorator
LogicalTree
logical root: System.Windows.Controls.Decorator
System.Windows.Controls.Decorator
visual root: System.Windows.Controls.Primitives.PopupRoot inherits from System.Windows.FrameworkElement
LogicalTree
System.Windows.Controls.Primitives.Popup
VisualTree
System.Windows.Controls.Grid
System.Windows.Controls.Grid
here it is: System.Windows.Controls.ToolBar
System.Windows.Controls.Grid
logical root: System.Windows.Controls.Grid
提前致谢!