我有一个场景,我有一个WPF TreeView控件,其项目有HierarchicalDataTemplate
。现在在HierarchicalDataTemplate
内,我有一个Label
,而Label
有一个ContextMenu
,其中包含Delete
的菜单项。删除菜单项绑定到名为DeleteCommand
的命令,该命令是已设置为DataType
的{{1}}的类的一部分。
现在,我想在ContextMenu的HierarchicalDataTemplate
菜单项TreeView
的{{1}}中传递CommandParameters
控件,以便我可以在删除时处理TreeViewItems的选择当前所选项目。
但是,如果我将Delete
绑定为DeleteCommand
或其他任何内容,除非绑定元素是CommandParameters
中的属性,否则它始终为null。
任何人都可以帮我解决问题因为我认为,我已经尝试了所有可能的东西,比如RelativeSource和AncestorType等,但它总是为空。对我来说,它看起来像是框架中的限制或错误。
答案 0 :(得分:17)
问题是ContextMenu是它自己的可视树的根,所以任何RelativeSource.FindAncestor绑定都不会超过ContextMenu。
一种解决方案是使用PlacementTarget属性从Label设置两阶段绑定:
<Label Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={
x:Type TreeView}}}">
<Label.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete" Command="{x:Static local:Commands.DeleteCommand}"
CommandParameter="{Binding PlacementTarget.Tag, RelativeSource={
RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
</ContextMenu>
</Label.ContextMenu>
</Label>
然而,这非常hacky。最好将MenuItem的CommandTarget属性设置为ContextMenu的PlacementTarget,并在TreeView上设置命令处理程序。这意味着您不必传递TreeView。
答案 1 :(得分:1)
<ContextMenu>
<MenuItem Header="Edit Item"
Command="{Binding EditItemCommand, Mode=OneWay}"
CommandParameter="{Binding Path=UIElement.(views:DataGridView.SelectedItems), RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
<ContextMenu>
答案 2 :(得分:0)
<MenuItem Header="..."
Command="{Binding Path=...}"
CommandParameter="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type ContextMenu}}}">
</MenuItem>
ContextMenu.PlacementTarget是Label,其中托管了menuitem。从Lavel,它的父Treeview是可访问的。
答案 3 :(得分:0)
对于 DataGrid 中的每个元素
<ContextMenu>
<MenuItem Header="Edit Item"
Command="{Binding EditItemCommand, Mode=OneWay}"
CommandParameter="{Binding Path=PlacementTarget.SelectedItem, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
<ContextMenu>
答案 4 :(得分:-1)
看看WPF CommandParameter Binding Problem。也许它可以提供一些关于发生了什么的指示。