命令绑定分层的DataTemplate绑定、命令、DataTemplate

由网友(路尽隐香处)分享简介:我有菜单在我的应用程序。我使用的是分层数据模板可视化的:<菜单项标题=主菜单的ItemsSource ={结合ApplicationMenu}>< MenuItem.ItemTemplate>< HierarchicalDataTemplate数据类型={X:tm类型:RMenuItem}...

我有菜单在我的应用程序。我使用的是分层数据模板可视化的:

 <菜单项标题=主菜单的ItemsSource ={结合ApplicationMenu}>
        < MenuItem.ItemTemplate>
            < HierarchicalDataTemplate数据类型={X:tm类型:RMenuItem}
                                      的ItemsSource ={绑定路径= ChildrenItems}>
                <菜单项标题={结合名}命令={结合RunOperationCommand}/>
            < / HierarchicalDataTemplate>
        < /MenuItem.ItemTemplate>
    < /菜单项>
 

菜单看起来像它应该,但命令每个菜单项不被解雇了!甚至更多 - 这是无界,这可能在调试器中可以看出:获得ICommand的属性访问器一直从未执行。 为什么会发生这样?

做和往常一样的作品完美的:

 <菜单>
    <菜单项标题=SomeHeader命令={结合RunOperationCommand}/>
<菜单>
 

解决方案

第一,在你的问题的第二个例子之间的不同之处在于,在第​​二code片断,绑定菜单项。命令于母公司的数据上下文,它具有 RunOperationCommand 定义。而在第一个例子中的 HierarchicalDataTemplate 要绑定到本地的DataContext,这是一个菜单项。它不具有相应的属性,所以结合失败。

WPF使用命令绑定

您有几种选择:

一个是你的菜单项的命令属性扩展,就像你已经在你的答案做了; 绑定到相对源在可视化树,它具有数据上下文的命令,如:假设该命令是在窗口的DataContext:

 <菜单项标题=主菜单的ItemsSource ={结合ApplicationMenu}>
        < MenuItem.ItemTemplate>
            < HierarchicalDataTemplate数据类型={X:tm类型:RMenuItem}
                                      的ItemsSource ={绑定路径= ChildrenItems}>
                <菜单项标题={结合名}
                          命令={绑定的RelativeSource = {的RelativeSource FindAncestor,AncestorType = {X:类型窗口}},路径= DataContext.RunOperationCommand}
                />
            < / HierarchicalDataTemplate>
        < /MenuItem.ItemTemplate>
    < /菜单项>
 

请从你的命令的StaticResource,类似这篇博客文章的方式

 < Window.Resources>
     < coreView:CommandReference X:关键=RunOperationCommand
                                命令={结合RunOperationCommand}/>
< /Window.Resources>

    <菜单项标题=主菜单的ItemsSource ={结合ApplicationMenu}>
        < MenuItem.ItemTemplate>
            < HierarchicalDataTemplate数据类型={X:tm类型:RMenuItem}
                                      的ItemsSource ={绑定路径= ChildrenItems}>
                <菜单项标题={结合名}
                          命令={的StaticResource RunOperationCommand}
                />
            < / HierarchicalDataTemplate>
        < /MenuItem.ItemTemplate>
    < /菜单项>
 

I have Menu in my app. I'm visualizing it using hierarchical data template:

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

menu looks like as it should, but Command for each menu item is not fired! Even more - it is not bounded, which could be seen in debugger: get accessor of ICommand Property has been never executed. Why it happens so?

Doing as usual works perfect:

<Menu>
    <MenuItem Header="SomeHeader" Command="{Binding RunOperationCommand}"/>
<Menu>

解决方案

The difference between the first and the second example in your question is that in the second code snippet you are binding MenuItem.Command to the parent's data context, which has the RunOperationCommand defined. Whereas in the first example with the HierarchicalDataTemplate you are binding to the "local" DataContext, which is a menu item. It doesn't have the appropriate property, so the binding fails.

You have several options:

one is to extend your menu items with the command property, like you did in your answer already; bind to the relative source up in the visual tree, which has the data context with the command, e.g. assuming that the command is in your window's 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>

Make a StaticResource from your command, similar to this blog post approach

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

阅读全文

相关推荐

最新文章