gpt4 book ai didi

WPF TreeView 上下文菜单命令参数

转载 作者:行者123 更新时间:2023-12-04 21:36:27 24 4
gpt4 key购买 nike

我有 TreeViewHierarchicalDataTemplate。在 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 绑定(bind)到菜单项。像往常一样在 ViewModell 类中定义的 AddPackageCommand。调用命令工作正常,但我在 CommandParameter 中始终有 null。我发现了一些类似于我的问题,但我不明白解决方案。例如:

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>

这是什么鬼...

无论如何,我在 CommandParameter 中有 TreeView 对象,而不是 TreeViewItem。我可以从 TreeView 获取 SelectedItem,但如何才能将 TreeViewItem 作为 CommandParameter 准确发送?

谢里丹

问题是为什么这不起作用。

CommandParameter="{Binding ElementName=_packageTreeView, Path=SelectedItem}"

这行得通

CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"

为什么 有时我可以使用直接的 TreeView 控件名称,有时我不能。据我了解,TreeView 控件和 ContextMenu 的 DataContext 不同,因为 ContextMenu 有自己的 VisualTree,它不是 的一部分TreeView ViaualTree.

不幸的是,这种方法也行不通,我又遇到了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 属性,将它绑定(bind)到 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>

最佳答案

您向我们展示了您已经有了答案...您到底为什么要发布关于同一主题的另一个问题,而不是简单地按照答案中的示例进行操作?它对您不起作用,因为您没有正确复制答案。

在您的示例帖子答案中,Tag属性设置为 TreeView控制应用菜单,但你还没有这样做。

你的下一个问题是你忽略了这个 Tag属性(property)再次在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 的属性(property), 这是 ContextMenu 的控件适用于或在本例中适用于 Treeview .

如果您还没有算出,这意味着 DataContextContextMenu现在设置为与 DataContext 相同的对象的 TreeView .如果这不是您想要的,因为您的 Command在不同的对象上,然后只需更改 Binding Tag 中的路径属性指向具有 Command 的对象所在的位置是。

为了简化这个过程,您可以做的最后一件事是向您的 View 模型/代码添加一个绑定(bind)到 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>

当然,这最后一部分假设您已将 View 模型/代码设置为 Tag TreeView 的属性(property).如果你还不明白这个,看看Context Menus in WPF WPF Tutorial.NET 上的页面。

更新>>>

我只是不明白你为什么提出这个问题。首先你说你不能做某事,但随后在另一篇文章中为我们提供了指向有效解决方案的链接。在尝试帮助你之后,你又说它确实有效,但你不知道为什么......但你又正确地回答了你自己的问题:

As I understand, matter is different DataContext of TreeView control and ContextMenu because ContextMenu has its own VisualTree and it is not the part of TreeView ViaualTree.

如您所说,ContextMenu有自己的视觉树。这意味着它不知道另一个可视化树中的控件,无论是否命名。但是,如果 ContextMenu.DataContext提供了一个对象,例如包含 View ,然后它可以知道另一个可视化树中的控件(更具体地说, View 中控件的可视化树)。

这整个问题似乎归结为您对 Binding 缺乏了解一般和Binding.Path语法更具体。请查看 MSDN 上的以下文章以获得有关此主题的更多帮助:

Binding.Path Property

Property Path Syntax

RelativeSource MarkupExtension

很多人在会走路之前尝试用 WPF 运行。

关于WPF TreeView 上下文菜单命令参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19133654/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com