我TreeView
HierarchicalDataTemplate
。在TreeView
我有ContextMenu
<TreeView Name="_packageTreeView" ItemsSource="{Binding PackageExtendedList}" Behaviors:TreeViewInPlaceEditBehavior.IsEditable="True">
<TreeView.ContextMenu>
<ContextMenu StaysOpen="true">
<MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}"
CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}">
<MenuItem.Icon>
<Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</TreeView.ContextMenu>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Childs}">bla bla bla</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
如您所见,我将Command
绑定到菜单项。通常在ViewModell类中定义AddPackageCommand。调用命令工作正常,但null
中始终有CommandParameter
。我发现了一些类似于我的问题,但我不明白解决方案。例如:
CommandParameters in ContextMenu in WPF
无论如何它对我不起作用:(我做错了什么?
更新
这似乎有效,但它完全相同,我不明白为什么CommandParameter
不能与TreeView.Name
一起使用。
CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"
例如,这样的样本工作正常
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding PackageTreeItemChangeCommand}" CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}"/>
</i:EventTrigger>
到底是什么......
无论如何,我在TreeView
中有CommandParameter
个对象,而不是TreeViewItem
。我可以从SelectedItem
获取TreeView
,但如何准确发送TreeViewItem
作为CommandParameter
?
致Sheridan
问题是为什么这不起作用。
CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}"
这有效
CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"
为什么有时我可以使用直接的TreeView控件名称,有时候我不能。
据我所知,问题是TreeView
控件和ContextMenu
的DataContext不同,因为ContextMenu
有自己的VisualTree,而不是TreeView
ViaualTree
的一部分。< / p>
不幸的是,这种方法也不起作用,我再次null
。我设置了TreeView.Tag,当然。
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={
RelativeSource Self}}" StaysOpen="true">
<MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}"
CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}">
<MenuItem.Icon>
<Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
这是最简单的方法,但如果我在ViewModel中有SelectedItem属性,则无法将其绑定到CommandParameter
,因为我已在ViewModel中使用它。
<MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}"
CommandParameter="{Binding SelectedItem}">
<MenuItem.Icon>
<Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
</MenuItem.Icon>
</MenuItem>
答案 0 :(得分:1)
你告诉我们你已经有了答案......为什么你在同一主题上发布了另一个问题,而不是简单地按照答案中的例子?它不适合您,因为您没有正确复制答案。
在回答示例中,Tag
属性设置为应用菜单的TreeView
控件,但您尚未执行此操作。
您的下一个问题是您在Tag
中再次忽略了此CommandParameter
属性...不知何故,您已从正确答案中更改此内容:
CommandParameter="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type ContextMenu}}}
在您的问题中:
CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type ContextMenu}}}"
您需要做的就是复制并粘贴它。尽管如此,你可能会有更多的运气:
<TreeView Tag="{Binding DataContext, RelativeSource={RelativeSource Self}}"
Name="_packageTreeView" ItemsSource="{Binding PackageExtendedList}"
Behaviors:TreeViewInPlaceEditBehavior.IsEditable="True">
<TreeView.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={
RelativeSource Self}}" StaysOpen="true">
<MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}"
CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}">
<MenuItem.Icon>
<Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</TreeView.ContextMenu>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Childs}">bla bla bla</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
查看TreeView.Tag
属性...这已设置为自己的DataContext
,这意味着现在可以将DataContext
TreeView
设置为Tag
在ContextMenu.DataContext
属性对象中。
接下来,查看Tag
属性...此设置为PlacementTarget
的{{1}}属性,ContextMenu
是Treeview
应用于DataContext
的控件,或者在这种情况下,ContextMenu
。
如果您还没有解决,这意味着DataContext
的{{1}}现在设置为与TreeView
的{{1}}相同的对象。如果这不是您想要的,因为您的Command
位于不同的对象上,那么只需将Binding
属性中的Tag
路径更改为指向具有{{1}的对象的任何位置是的。
您可以做的最后一件事就是将属性添加到绑定到Command
属性的视图模型/代码后面:
TreeView.SelectedItem
然后,您只需为<TreeView SelectedItem="{Binding SelectedItem}"... />
:
CommandParameter
本课程的最后一部分假定您已将视图模型/代码设置为<MenuItem Header="Добавить пакет" Height="20" Command="{Binding AddPackageCommand}"
CommandParameter="{Binding SelectedItem}">
<MenuItem.Icon>
<Image Source="/Resources/ManualAdd.png" Width="15" Height="15"></Image>
</MenuItem.Icon>
</MenuItem>
的{{1}}属性。如果您仍然不明白这一点,请查看WPF Tutorial.NET上的Context Menus in WPF页面。
更新&gt;&gt;&gt;
我根本不明白你为什么发布这个问题。首先,你说你做不了什么,但后来在另一篇文章中为我们提供了一个有效解决方案的链接。在试图帮助你之后,你说它确实有效,但你不知道为什么......但是你再次正确地回答了你自己的问题:
据我所知,问题是TreeView控件和ContextMenu的不同DataContext,因为ContextMenu有自己的VisualTree,它不是TreeView ViaualTree的一部分。
如你所说,Tag
有自己的视觉树。这意味着它不知道另一个可视树中的名称或其他控件。但是,如果为TreeView
提供了一个对象(如包含视图),则可以知道另一个可视树中的控件(更具体地说,是控件中的控件的可视树)。视图)。
整个问题似乎是由于您对ContextMenu
的一般性和ContextMenu.DataContext
语法缺乏了解。有关此主题的更多帮助,请查看MSDN上的以下文章:
RelativeSource MarkupExtension
很多人试图在他们走路之前使用WPF。