Wpf MenuItem数据绑定

Wpf MenuItem数据绑定,wpf,xaml,data-binding,contextmenu,menuitem,Wpf,Xaml,Data Binding,Contextmenu,Menuitem,我已经为这件事困惑了一天左右,运气不好——我可能错过了一些明显的东西。基本上,我有一个包含两个项目的上下文菜单。一个是静态声明的,并绑定到命令。另一个没有自己的命令,但绑定到viewmodels集合。因此,从视觉上看,菜单应该类似于: 删除 加 项目1 项目2 根据上下文菜单绑定到的对象,项目会有所不同。最初我有这样的想法: <ContextMenu x:Key="itemContextMenu"> <MenuItem He

我已经为这件事困惑了一天左右,运气不好——我可能错过了一些明显的东西。基本上,我有一个包含两个项目的上下文菜单。一个是静态声明的,并绑定到命令。另一个没有自己的命令,但绑定到viewmodels集合。因此,从视觉上看,菜单应该类似于:

  • 删除
    • 项目1
    • 项目2
根据上下文菜单绑定到的对象,项目会有所不同。最初我有这样的想法:

    <ContextMenu x:Key="itemContextMenu">
        <MenuItem Header="_Delete"
                  Command="{Binding DeleteCommand}" />
        <MenuItem Header="_Add" DataContext=""
                  ItemsSource="{Binding AvailableTypes}">
            <MenuItem.ItemTemplate>
                <DataTemplate>
                    <MenuItem Header="{Binding Path=ItemType.Name}"
                              Command="{Binding Path=AddItemCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
                              CommandParameter="{Binding}" />
                </DataTemplate>
            </MenuItem.ItemTemplate>
        </MenuItem>
    </ContextMenu>

这是可行的,但给了我其他人体验过的嵌套菜单项。基于stackoverflow上的几个线程,我尝试了以下方法:

    <ContextMenu x:Key="itemContextMenu">
        <MenuItem Header="_Delete"
                  Command="{Binding DeleteCommand}" />
        <MenuItem Header="_Add" 
                  ItemsSource="{Binding AvailableTypes}">
            <MenuItem.ItemContainerStyle>
                <Style TargetType="MenuItem">                        
                    <Setter Property="Header"
                            Value="{Binding Path=ItemType.Name}" />
                    <Setter Property="Command"
                            Value="{Binding Path=AddItemCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}" />
                    <Setter Property="CommandParameter"
                            Value="{Binding}" />
                </Style>
            </MenuItem.ItemContainerStyle>
        </MenuItem>
    </ContextMenu>

但是,当我这样做时,我的绑定都会失败,并出现如下错误:

BindingExpression路径错误:在“对象”“字符串”上找不到“ItemType”属性

BindingExpression路径错误:在“对象”“网格”上找不到“AddItemCommand”属性

对我来说,当我使用ItemContainerStyle时,DataContext正在丢失。我错过了什么

编辑:

我想我在这里有些小意思,所以我进一步简化了示例,试图缩小问题的范围

工作但布局扭曲:

    <ContextMenu x:Key="itemContextMenu">
        <MenuItem Header="_Delete" />
        <MenuItem Header="_Add" DataContext=""
                  ItemsSource="{Binding AvailableTypes}">
            <MenuItem.ItemTemplate>
                <DataTemplate>
                    <MenuItem Header="{Binding Path=ItemType.Name}" />
                </DataTemplate>
            </MenuItem.ItemTemplate>
        </MenuItem>
    </ContextMenu>

无法使用BindingExpression错误:

    <ContextMenu x:Key="itemContextMenu">
        <MenuItem Header="_Delete" />
        <MenuItem Header="_Add" 
                  ItemsSource="{Binding AvailableTypes}">
            <MenuItem.ItemContainerStyle>
                <Style TargetType="MenuItem">                        
                    <Setter Property="Header"
                            Value="{Binding Path=ItemType.Name}" />
                </Style>
            </MenuItem.ItemContainerStyle>
        </MenuItem>
    </ContextMenu>


显然这是3.5中的一个bug。我将我的项目升级到4.0,现在一切正常。

您没有说明所需的结果。所需的结果是将AvailableTypes集合的内容(在父菜单项的DataContext上)呈现为子菜单项,但没有我最初的解决方案引入的可视工件。很抱歉,我认为这更清楚。所有这些代码都不正确,在您的第一个示例中,应该已经存在绑定错误,因为您可以忘记从
上下文菜单中使用
相对资源。另外,目标
网格上几乎没有command属性。很抱歉,在第一个示例中,应该是DataContext.AddItemCommand。但是,是的,除了布局问题,它确实像冠军一样工作。显然,使用ItemTemplate和ItemContainerStyle的规则是不同的,这就是我的困惑所在。使用ItemContainerStyle时,如何绑定到ItemsSource中的模板化项?