ContextMenu.ItemSource绑定问题

时间:2016-01-27 11:21:32

标签: wpf xaml

我有一个静态资源,定义如下:

    <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:路径= Horizo​​ntalContentAlignment;的DataItem = NULL; target元素是'MenuItem'(Name =''); target属性是'Horizo​​ntalContentAlignment'(类型'Horizo​​ntalAlignment')

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

1 个答案:

答案 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将其部分属性(VerticalContentAlignmentItemsControl)绑定到RelativeSource。问题是它们嵌入CompositeCollection内部,不支持这种绑定 - 请参阅this文章。

即使您以这种方式覆盖XAML中的此绑定,也会出现问题:

<MenuItem Command="ApplicationCommands.Cut" CommandTarget="{Binding}"
     HorizontalContentAlignment="Center"  VerticalContentAlignment="Center"/>

可能这个问题有一些解决方法,但我个人会忽略这些错误。它们不会破坏您应用程序中的任何内容,不是吗?