当前位置: 首页 > news >正文

ContextMenu的Item如何绑定命令

<UserControl x:Class="ATE.View.需求管理View"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ATE.View"xmlns:i="http://schemas.microsoft.com/xaml/behaviors"xmlns:vm="clr-namespace:ATE.VM"mc:Ignorable="d"FontFamily="Microsoft YaHei"x:Name="root"d:DesignHeight="450" d:DesignWidth="800"><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="*" /><ColumnDefinition Width="auto" /><ColumnDefinition Width="5*" /></Grid.ColumnDefinitions><GroupBox Grid.Column="0"Margin="10"Header="本地数据"><TreeView ItemsSource="{Binding RootNodes}"Tag="{Binding DataContext, ElementName=root}"x:Name="treeView"><TreeView.Resources><!-- 组节点模板 --><HierarchicalDataTemplate DataType="{x:Type vm:GroupNode}"ItemsSource="{Binding Children}"><StackPanel Orientation="Horizontal"x:Name="stackPanel"><Image Source="{Binding Icon}"Width="16"Height="16" /><TextBlock Text="{Binding Name}"Margin="5,0" /><StackPanel.ContextMenu><ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"><MenuItem Header="添加分组"Command="{Binding AddGroupCommand}"CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu},Path=PlacementTarget.DataContext}" /><MenuItem Header="添加元素"Command="{Binding AddElementCommand}"CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu},Path=PlacementTarget.DataContext}" /><Separator /><MenuItem Header="删除"Command="{Binding DeleteNodeCommand}"CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}" /></ContextMenu></StackPanel.ContextMenu></StackPanel></HierarchicalDataTemplate><!-- 元素节点模板 --><DataTemplate DataType="{x:Type vm:ElementNode}"><StackPanel Orientation="Horizontal"Tag="{Binding DataContext, ElementName=root}"><Image Source="{Binding Icon}"Width="16"Height="16" /><TextBlock Text="{Binding Name}"Margin="5,0"FontStyle="Italic" /><StackPanel.ContextMenu><ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"><MenuItem Header="删除"Command="{Binding DeleteNodeCommand}"CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}" />  </ContextMenu></StackPanel.ContextMenu></StackPanel></DataTemplate></TreeView.Resources></TreeView></GroupBox></Grid>
</UserControl>

首先要理解为什么不能直接绑定命令呢

正常情况,我们的控件都是在可视化树上,UserControl继承DataContext,一般都可以直接绑定,如果是一些定制化容器如ListBox,ItemsControl这种就需要用下面这种方法来绑定,但这些都是建立在控件在可视化树上

Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}, Path=DataContext.EditUserCommand}" CommandParameter="{Binding}"

ContextMenu属于PopUp控件,不在可视化树上就不能用上述方法

如何绑定不在可视化树上的控件

用控件的tag来中转

上面那个例子,要绑定TreeView中的ContextMenu

首先要让ContextMenu的上层控件的tag来绑定UserControl的DataContext

<UserControl x:Class="ATE.View.需求管理View"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ATE.View"xmlns:i="http://schemas.microsoft.com/xaml/behaviors"xmlns:vm="clr-namespace:ATE.VM"mc:Ignorable="d"FontFamily="Microsoft YaHei"x:Name="root"d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Orientation="Horizontal"x:Name="stackPanel"Tag="{Binding DataContext, ElementName=root}">

为什么一定要上层控件能,因为ContextMenu里面有一个属性PlacementTarget,他指向的就是上层空间,ContextMenuStackPanel包裹,所以指向StackPanel

<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"><MenuItem Header="删除"Command="{Binding DeleteNodeCommand}"CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}" />  
</ContextMenu>

一定要用RelativeSource指向自己,如果不这样的话,Wpf会在可视化树中找PlacementTarget属性,很显然是找不到的,这样就可也绑定命令了,只有通过 PlacementTarget.DataContext,才能精确拿到你右键的那个节点。

http://www.xdnf.cn/news/1101079.html

相关文章:

  • “28项评测23项SOTA——GLM-4.1V-9B-Thinking本地部署教程:10B级视觉语言模型的性能天花板!
  • 【AI大模型】BERT微调文本分类任务实战
  • 拼数(字符串排序)
  • 力扣面试150(29/100)
  • 问题 C: 为美好的世界献上爆炎(博弈论)
  • 如何在 Windows 10 上安装设置 Apache Kafka
  • 聊聊AI大模型的上下文工程(Context Engineering)
  • 你见过的最差的程序员是怎样的?
  • Redis底层数据结构
  • CSS3的核心功能介绍及实战使用示例
  • 提示工程:解锁大模型潜力的核心密码
  • 库存订单管理系统:3月份开源项目汇总
  • linux中cmake编译项目
  • Django母婴商城项目实践(二)
  • 1.1.2 运算符与表达式——AI教你学Django
  • 3.检查函数 if (!CheckStart()) return 的妙用 C#例子
  • Vue3 Pinia
  • php中调用对象的方法可以使用array($object, ‘methodName‘)?
  • DSPy:用编程思维驯服大模型的新范式
  • 2025年主流数据库连接池推荐:从原理到场景的深度解析
  • Java 大视界 -- Java 大数据在智能医疗远程手术机器人操作数据记录与分析中的应用(342)
  • 传输层协议UDP原理
  • 二分查找1
  • JavaScript加强篇——第五章 DOM节点(加强)与BOM
  • 企业培训笔记:Vue3前端框架配置
  • 销售数据可视化分析项目
  • 专题:2025云计算与AI技术研究趋势报告|附200+份报告PDF、原数据表汇总下载
  • 如何选择数据可视化工具?从设计效率到图表表现力全解读
  • Spring之我见-Spring循环依赖为啥是三级缓存?
  • uniApp实战五:自定义组件实现便捷选择