菜单项数据绑定

3
我已经苦思冥想了一天,但还是没有找到答案——很可能我错过了什么显而易见的地方。基本上,我有一个带有两个项目的上下文菜单。一个是静态声明的,并绑定到一个命令。另一个没有自己的命令,但绑定到一组视图模型。因此,从视觉上看,菜单应该如下所示:
- 删除 - 添加 - 项目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路径错误:在“对象”'“String”'上未找到“ItemType”属性

BindingExpression路径错误:在“对象”'“Grid”'上未找到“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>

您没有说明您想要的结果。 - Jake Berger
期望的结果是将父级菜单项DataContext的AvailableTypes集合内容呈现为子菜单项,但不带有我原始解决方案引入的视觉瑕疵。抱歉,我以为这更清楚明了。 - superstator
所有这些代码都不符合逻辑,在你的第一个示例中,由于你不能在“ContextMenu”内部使用“RelativeSource”,所以已经应该出现绑定错误。此外,目标“Grid”上几乎没有命令属性。 - H.B.
抱歉,在第一个示例中应该是DataContext.AddItemCommand。 但是,它确实可以像冠军一样工作,除了布局问题之外。显然,在使用ItemTemplate与ItemContainerStyle时,规则是不同的,这就是我的困惑所在。当使用ItemContainerStyle时,我如何将数据绑定到模板化的项(templated items)? - superstator
1个回答

1

显然这是3.5版本中的一个bug。我将我的项目升级到4.0,现在一切都按预期工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接