【发布时间】:2015-01-18 14:11:47
【问题描述】:
我正在使用命令模式和(除其他外)TreeViewItem 上的上下文菜单,它使用 HierarchicalDataTemplates。 MainWindowViewModel(Window 的静态资源)具有公开单例对象的属性,这些对象又具有表示命令的属性。我能够很好地执行命令,但是某些命令需要将 TreeViewItem 的 DataContext 作为 CommandParameter 传递。
这是一个具体的例子: 树的一个节点将 ItemsSource 绑定到各个 AnalysisMain 对象的 ObservableCollection。每个生成的子节点都有一个 ContextMenu(具有绑定到 AnalysisController 的 DataContext),它具有(除其他外)一个 Remove MenuItem。 Remove MenuItem 的 Command 属性绑定到 AnalysisController 单例对象上的 CommandRemove 命令(它执行得很好)。但这也需要将 CommandParameter 绑定到充当树中子节点的 DataContext 的 AnalysisMain 对象。我尝试使用将 AncestorType 设置为 TreeViewItem 并将路径设置为 DataContext 的 RelativeSource:
<HierarchicalDataTemplate DataType="{x:Type vmAnalysis:AnalysisMain}">
<WrapPanel Orientation="Horizontal">
<Image Source="Analysis\Icon_Analysis_Main_16_Normal.png" Margin="0,0,2,0" Width="16"/>
<TextBlock Text="{Binding TreeViewTitle}">
<TextBlock.ContextMenu>
<ContextMenu DataContext="{StaticResource mainWindowViewModel}">
<MenuItem Header="Remove" Command="{Binding Path=AnalysisController.CommandRemove}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=4}, Path=DataContext}">
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</WrapPanel>
</HierarchicalDataTemplate>
如果没有设置 AncestorLevel,当我打开 ContextMenu 时,我会在输出窗口中看到以下内容:
System.Windows.Data 错误:4:找不到与引用'RelativeSource FindAncestor,AncestorType='System.Windows.Controls.TreeViewItem',AncestorLevel='4''的绑定源。绑定表达式:路径=数据上下文;数据项=空;目标元素是'MenuItem'(名称='');目标属性是'CommandParameter'(类型'Object')
我尝试了几个 AncestorLevel 的值,但均无济于事。
通过检查 Christian Mosers WPF Inspector 中的可视化树,我在可视化树中看不到上下文菜单。虽然 TreeViewItem 显示了 DataContext 对象。我只需要一种“导航”到它的方法来绑定它。
作为替代方案,我尝试单独保留 ContextMenu DataContext 并将命令绑定的源设置为指向 AnalysisController。这也适用于执行命令,但我无法为 CommandParameter 绑定到 TreeViewItem 的 DataContext:
<ContextMenu>
<MenuItem Header="Remove" Command="{Binding Source={StaticResource mainWindowViewModel}, Path=AnalysisController.CommandRemove}"
CommandParameter="{Binding Source={RelativeSource Self}, Path=DataContext}">
</MenuItem>
</ContextMenu>
我也尝试过只使用 CommandParameter="{Binding}",这也不起作用。 (在这两种情况下,我只是将 null 作为参数发送。没有警告/错误被写入输出窗口。)编辑:对于其他有这个问题的人,第二个选项从一开始就注定了,因为我错误地输入了 Source ={RelativeSource Self},它将引用 MenuItem 而不是 TreeViewItem。然而,用 AncestorType / AncestorLevel 改变它没有任何区别。
【问题讨论】:
-
我可能对与
CommandParameter绑定相关的确切错误有误,实际上CanExecute中的参数为null(意味着绑定不起作用)但在Execute回调中,参数为通过确定。对于我之前发布的代码,您可以尝试在输出窗口中查看是否有任何错误通知。 -
我检查了(覆盖CanExecute始终返回true),参数仍然为null。
标签: c# wpf data-binding contextmenu command-pattern