我有一个静态资源,定义如下:
<ContextMenu x:Key="TestContextMenu" DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}">
<MenuItem Command="ApplicationCommands.Cut"/>
<!--<ContextMenu.ItemsSource>
<CompositeCollection>
<MenuItem Command="ApplicationCommands.Cut"/>
</CompositeCollection>
</ContextMenu.ItemsSource>-->
</ContextMenu>
我的应用程序工作得很好。但是,我希望能够在上下文菜单中添加额外的项目。因此,我没有添加菜单项,而是想使用CompositeCollection,然后遇到绑定问题。我把问题最小化了,结果就是这样。当我评论MenuItem并取消注释ContextMenu.ItemSource
时,我收到此错误:
System.Windows.Data错误:4:无法找到与引用'RelativeSource FindAncestor绑定的源,AncestorType ='System.Windows.Controls.ItemsControl',AncestorLevel ='1''。 BindingExpression:路径= HorizontalContentAlignment;的DataItem = NULL; target元素是'MenuItem'(Name =''); target属性是'HorizontalContentAlignment'(类型'HorizontalAlignment')
如果datacontext在第一种情况下是正确的,为什么在第二种情况下它不再正确?
编辑:我不想动态地向上下文菜单添加项目。我想使用这个contextmenu作为一种“基本上下文菜单”,提供从复合集合资源中剪切/复制和粘贴。在某些地方,我想要的不仅仅是这三个,我可以使用自定义上下文菜单,使用相同的集合和这些额外的项目。只是为了澄清这是我想到的xaml,但我把问题简化为上面的简单部分。
<CompositeCollection x:Key="TreeViewItemContextMenuItems">
<MenuItem Command="ApplicationCommands.Cut" CommandTarget="{Binding}"/>
<MenuItem Command="ApplicationCommands.Copy" CommandParameter="{Binding}"/>
<MenuItem Command="ApplicationCommands.Paste" CommandParameter="{Binding}"/>
<Separator/>
<MenuItem Command="ApplicationCommands.Delete" CommandParameter="{Binding}"/>
</CompositeCollection>
<ContextMenu x:Key="TreeViewItemContextMenu" DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}">
<ContextMenu.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{StaticResource TreeViewItemContextMenuItems}" />
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
答案 0 :(得分:1)
如果您想动态填充ContextMenu
,更好的解决方案如下:
<ContextMenu
x:Key="TestContextMenu"
ItemsSource="{Binding MenuItems}">
</ContextMenu>
我删除了DataContext="{Binding Path=PlacementTarget...}}"
并添加了此ItemsSource="{Binding MenuItems}"
。 MenuItems
是用作数据上下文的对象的属性。以下是一个使用示例:
<Window>
...
<ItemsControl ContextMenu="{StaticResource ResourceKey=TestContextMenu}">
...
</ItemsControl>
</Window
在这种情况下,上下文菜单将继承ItemsControl
的数据上下文,而后者将继承Window
的数据上下文。
如果您不想删除DataContext="{Binding Path=PlacementTarget...}}"
,请使用以下代码:
<ContextMenu
x:Key="TestContextMenu"
DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}"
ItemsSource="{Binding DataContext.MenuItems}">
</ContextMenu>
修改强>
您收到这些错误,因为默认情况下MenuItem
控件尝试使用HorizontalContentAlignment
将其部分属性(VerticalContentAlignment
和ItemsControl
)绑定到RelativeSource
。问题是它们嵌入CompositeCollection
内部,不支持这种绑定 - 请参阅this文章。
即使您以这种方式覆盖XAML中的此绑定,也会出现问题:
<MenuItem Command="ApplicationCommands.Cut" CommandTarget="{Binding}"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
可能这个问题有一些解决方法,但我个人会忽略这些错误。它们不会破坏您应用程序中的任何内容,不是吗?