【WPF】右键菜单ContextMenu可点击区域太小的问题
问题描述
正常使用右键菜单ContextMenu时,如果菜单项是不变的,可以直接在XAML中写死,如下是给一个Button按钮添加了右键菜单功能。
<Button Content="Test" Width="100" Height="30">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="1"/>
<MenuItem Header="1123"/>
<MenuItem Header="11234134532"/>
<MenuItem Header="1234532"/>
<MenuItem Header="1234"/>
<MenuItem Header="13245324532543253"/>
</ContextMenu>
</Button.ContextMenu>
</Button>

此时整个MenuItem菜单项都是可以响应点击的。
然而项目中通常右键菜单项MenuItem的内容是不固定的,是通过ItemsSource绑定了集合。集合使用的数据内容是可以动态修改的,在XAML中只是写数据模板ItemTemplate。代码改造一下如下。
XAML:ItemSource绑定列表DataList,MenuItem中显示的是DataList集合中的每个自定义对象的Num属性。
<Button Content="Test" Width="100" Height="30">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding DataList, Mode=TwoWay}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Header="{Binding Num}"
Command="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.YourCommand}"
CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}"/>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</Button.ContextMenu>
</Button>
自定义的实体类Student.cs。
public class Student
{
public string Num { get; set; }
public int Age { get; set; }
}
ViewModel:定义DataList集合。
private ObservableCollection<Student> dataList;
public ObservableCollection<Student> DataList
{
get { return dataList; }
set { dataList = value; }
}
给DataList填充数据。
DataList = new ObservableCollection<Student>();
DataList.Add(new Student() { Num = "", Age = });
DataList.Add(new Student() { Num = "", Age = });
DataList.Add(new Student() { Num = "", Age = });
DataList.Add(new Student() { Num = "", Age = });
DataList.Add(new Student() { Num = "", Age = });
DataList.Add(new Student() { Num = "", Age = });
运行后即可发现问题。

仔细观察上图运行效果,每个菜单项是嵌套在条目内部的,只有点击到中间深色区域才能触发菜单项的点击事件!点击左右两端浅色部分也能使菜单项关闭,但不会触发菜单项的点击事件!
解决方案
最初的想法是给内部被嵌套的MenuItem改样式,改为Padding=0应该就能使其扩大到紧贴整个条目区域。
<Button Content="Test" Width="100" Height="30">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding DataList, Mode=TwoWay}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Padding" Value="-33,0,-63,0"/>
</Style>
</ContextMenu.ItemContainerStyle>
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem Header="{Binding Num}"
Command="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.YourCommand}"
CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}"/>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</Button.ContextMenu>
</Button>

通过ContextMenu.ItemContainerStyle设置样式的Padding属性后,看上去菜单项已经覆盖了整个条目,但点击时依然是左右两端无法响应点击事件,只有中间部分能响应到!(测试的点击事件已被绑定到YourCommand命令中,此处已省略)
谷歌一下,看看别人是怎么处理该问题的。
参考:
- https://social.msdn.microsoft.com/Forums/vstudio/en-US/188e6bad-352a-4e7d-a3bb-0a88f7760529/datatemplate-can-not-access-menuitemclick-attribute?forum=wpf
- https://stackoverflow.com/questions/44763405/c-sharp-wpf-contextmenu-menuitem-does-not-react-to-click
上面第一篇文章中,老外的意见是不要在ItemTemplate中嵌套MenuItem,改为嵌套TextBlock。试了一下发现没用。。
根据第二篇中的回复,改为不用DataTemplate,完全在ContextMenu.ItemContainerStyle中设置菜单项的属性,试用后生效了。
<Button Content="Test" Width="100" Height="30">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding DataList, Mode=TwoWay}" Padding="0">
<!-- 消除ItemTemplate造成的内部MenuItem嵌套,导致左右两端无法响应点击的问题 -->
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Num}"/>
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.YourCommand}"/>
<Setter Property="CommandParameter" Value="{Binding RelativeSource={x:Static RelativeSource.Self}}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Button.ContextMenu>
</Button>
此时MenuItem菜单项覆盖了整个条目,且点击左右两端都能触发点击事件了!
【WPF】右键菜单ContextMenu可点击区域太小的问题的更多相关文章
- ASP.NET Menu控件点击区域太小解决方法
ASP.NET自带的Menu控件点击区域比较小,基本就是文本范围和图片范围,在区域外虽然选择的项有颜色变化,但是这个时候点击是没有用的,体验不是很好 检查前台生成的HTML,是用td嵌套a标签,a标签 ...
- jQuery右键菜单contextMenu实例
URL: http://www.cnblogs.com/whitewolf/archive/2011/09/28/2194795.html http://www.blogjava.net/superc ...
- ExtJS配置TabPanel的鼠标右键菜单(ContextMenu)功能
更新记录 2022年6月14日 发布. 2022年6月13日 初稿. TabPanel的鼠标右键菜单(ContextMenu)功能介绍 开源的TabPanel组件很少做到拖拽调整tab顺序功能的,支持 ...
- 传递给系统调用的数据区域太小。 (异常来自 HRESULT:0x8007007A)
在做结构体向字节数组转换的时候,常遇到"传递给系统调用的数据区域太小"的错误,究其原因是因为英文与汉字的编码方式不同,一个汉字等于两个字节,而一个英文字母等于1个字节.所以,对于如 ...
- WPF 如何控制右键菜单ContextMenu的弹出
在具体做一些项目的时候,有时候需要需要先左键点击某个节点,然后再右键点击节点的时候才弹出右键菜单,所以直接右键点击时需要禁用掉右键菜单,这里比如我们为Grid添加了ContextMenu,但是我们需要 ...
- jQuery右键菜单ContextMenu使用笔记
插件下载地址:http://www.trendskitchens.co.nz/jquery/contextmenu/jquery.contextmenu.r2.packed.js 和http://ww ...
- jQuery右键菜单contextMenu使用实例
在最近项目中需要频繁的右键菜单操作.我采用了contextMenu这款jQuery插件. 参考网址:http://www.jb51.net/article/58709.htm 官网demo http: ...
- Jquery 右键菜单(ContextMenu)插件使用记录
目前做的项目需要在页面里面用右键菜单,在网上找到两种jquery的右键菜单插件,但是都有各种问题.所以就自己动手把两种插件结合了下. 修改后的右键菜单插架可以根据绑定的触发页面元素不同,复用同一个菜单 ...
- HP1020打印机“传递给系统调用的数据区域太小” 如何处理?
如果电脑上曾经安装过 HP LaserJet 激光打印机的驱动程序,重新安装驱动程序之前,需要完全卸载以前安装的驱动程序,否则可能会出现无法找到设备或者安装不上驱动程序的现象. 安装网站下载的即插即用 ...
随机推荐
- 步进电机驱动器 和H桥
http://bbs.eeworld.com.cn/thread-489952-1-1.html
- linux下配置tomcat集群的负载均衡
linux下配置tomcat集群的负载均衡 一.首先了解下与集群相关的几个概念集群:集群是一组协同工作的服务实体,用以提供比单一服务实体更具扩展性与可用性的服务平台.在客户端看来,一个集群就象是一个服 ...
- 有关 Windows 10 中“适用于 Linux 的 Windows 子系统(Beta)”
1.如何启用?(未来应该可从应用商店中直接安装) 在"控制面板"的"启用或关闭 Windows 功能"中进行勾选安装.(安装完成后需要重新启动) 2.然后呢? ...
- 【Android UI】如何做一个纯粹的Android app UI 设计
原文:http://android.eoe.cn/topic/summary 许多开发者会在多个平台上发布应用.如果您打算为 Android 开发应用,请记住在不同的平台需要遵守不同的要求和惯例.在某 ...
- Serizlizable
关闭 忧郁王子的专栏 伟大的意大利,伟大的罗伯特-巴乔 目录视图 摘要视图 订阅 赠书 | 异步2周年,技术图书免费选 每周荐书:分布式.深度学习算法.iOS(评论送书) ...
- 牛腩记账本core版本源码
很简单的一个记账本项目,无非就是数据库的增删查改,采用vs2017 + asp.net core + mysql + dapper + layui, 其中访问mysql数据库用的是dapper, 界面 ...
- Atitit jquery 1.4--v1.11 v1.12 v2.0 3.0 的新特性
Atitit jquery 1.4--v1.11 v1.12 v2.0 3.0 的新特性 1.1. Jquery1.12 jQuery 2.2 和 1.12 新版本发布 - OPEN资讯.h ...
- JavaWEB springmvc 使用定时任务
1.配置web.xml 在web.xml配置使用springmvc框架,其他配置略. <display-name>xxx.com</display-name> <!-- ...
- 使用 RestTemplate 调用 restful 服务
什么是RestTemplate? RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效 ...
- 深入源码分析Java线程池的实现原理
程序的运行,其本质上,是对系统资源(CPU.内存.磁盘.网络等等)的使用.如何高效的使用这些资源是我们编程优化演进的一个方向.今天说的线程池就是一种对CPU利用的优化手段. 通过学习线程池原理,明白所 ...