命令绑定在分层数据模板中

And*_*aev 7 .net binding command hierarchicaldatatemplate

我的应用程序中有菜单.我正在使用分层数据模板将其可视化:

    <MenuItem Header="Main menu" ItemsSource="{Binding ApplicationMenu}" >
        <MenuItem.ItemTemplate>                    
            <HierarchicalDataTemplate DataType="{x:Type tm:RMenuItem}" 
                                      ItemsSource="{Binding Path=ChildrenItems}">                        
                <MenuItem Header="{Binding Name}" Command="{Binding RunOperationCommand}" />
            </HierarchicalDataTemplate>
        </MenuItem.ItemTemplate>
    </MenuItem>
Run Code Online (Sandbox Code Playgroud)

菜单看起来应该如此,但每个菜单项的命令都没有被触发!更多 - 它没有限制,可以在调试器中看到:ICommand属性的访问器从未被执行过.为什么会这样?

像往常一样工作完美:

<Menu>
    <MenuItem Header="SomeHeader" Command="{Binding RunOperationCommand}"/>
<Menu>
Run Code Online (Sandbox Code Playgroud)

Max*_*kin 7

您的问题中第一个和第二个示例之间的区别在于,在第二个代码段中,您绑定MenuItem.Command到父级的数据上下文,该上下文已RunOperationCommand定义.而在第一个示例中,HierarchicalDataTemplate您将绑定到"本地"DataContext,这是一个菜单项.它没有适当的属性,因此绑定失败.

你有几个选择:

  • 一种是使用命令属性扩展菜单项,就像你在答案中所做的那样;
  • 绑定到可视树中的相对源,它具有命令的数据上下文,例如假设命令在窗口的DataContext中:

    <MenuItem Header="Main menu" ItemsSource="{Binding ApplicationMenu}" >
        <MenuItem.ItemTemplate>                    
            <HierarchicalDataTemplate DataType="{x:Type tm:RMenuItem}" 
                                      ItemsSource="{Binding Path=ChildrenItems}">                        
                <MenuItem Header="{Binding Name}" 
                          Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.RunOperationCommand}" 
                />
            </HierarchicalDataTemplate>
        </MenuItem.ItemTemplate>
    </MenuItem>
Run Code Online (Sandbox Code Playgroud)

<Window.Resources>
     <coreView:CommandReference x:Key="RunOperationCommand"
                                Command="{Binding RunOperationCommand}" />
</Window.Resources>

    <MenuItem Header="Main menu" ItemsSource="{Binding ApplicationMenu}" >
        <MenuItem.ItemTemplate>                    
            <HierarchicalDataTemplate DataType="{x:Type tm:RMenuItem}" 
                                      ItemsSource="{Binding Path=ChildrenItems}">                        
                <MenuItem Header="{Binding Name}" 
                          Command="{StaticResource RunOperationCommand}" 
                />
            </HierarchicalDataTemplate>
        </MenuItem.ItemTemplate>
    </MenuItem>
Run Code Online (Sandbox Code Playgroud)