问题描述

正常使用右键菜单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命令中,此处已省略)

谷歌一下,看看别人是怎么处理该问题的。

参考:

  1. https://social.msdn.microsoft.com/Forums/vstudio/en-US/188e6bad-352a-4e7d-a3bb-0a88f7760529/datatemplate-can-not-access-menuitemclick-attribute?forum=wpf
  2. 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可点击区域太小的问题的更多相关文章

  1. ASP.NET Menu控件点击区域太小解决方法

    ASP.NET自带的Menu控件点击区域比较小,基本就是文本范围和图片范围,在区域外虽然选择的项有颜色变化,但是这个时候点击是没有用的,体验不是很好 检查前台生成的HTML,是用td嵌套a标签,a标签 ...

  2. jQuery右键菜单contextMenu实例

    URL: http://www.cnblogs.com/whitewolf/archive/2011/09/28/2194795.html http://www.blogjava.net/superc ...

  3. ExtJS配置TabPanel的鼠标右键菜单(ContextMenu)功能

    更新记录 2022年6月14日 发布. 2022年6月13日 初稿. TabPanel的鼠标右键菜单(ContextMenu)功能介绍 开源的TabPanel组件很少做到拖拽调整tab顺序功能的,支持 ...

  4. 传递给系统调用的数据区域太小。 (异常来自 HRESULT:0x8007007A)

    在做结构体向字节数组转换的时候,常遇到"传递给系统调用的数据区域太小"的错误,究其原因是因为英文与汉字的编码方式不同,一个汉字等于两个字节,而一个英文字母等于1个字节.所以,对于如 ...

  5. WPF 如何控制右键菜单ContextMenu的弹出

    在具体做一些项目的时候,有时候需要需要先左键点击某个节点,然后再右键点击节点的时候才弹出右键菜单,所以直接右键点击时需要禁用掉右键菜单,这里比如我们为Grid添加了ContextMenu,但是我们需要 ...

  6. jQuery右键菜单ContextMenu使用笔记

    插件下载地址:http://www.trendskitchens.co.nz/jquery/contextmenu/jquery.contextmenu.r2.packed.js 和http://ww ...

  7. jQuery右键菜单contextMenu使用实例

    在最近项目中需要频繁的右键菜单操作.我采用了contextMenu这款jQuery插件. 参考网址:http://www.jb51.net/article/58709.htm 官网demo http: ...

  8. Jquery 右键菜单(ContextMenu)插件使用记录

    目前做的项目需要在页面里面用右键菜单,在网上找到两种jquery的右键菜单插件,但是都有各种问题.所以就自己动手把两种插件结合了下. 修改后的右键菜单插架可以根据绑定的触发页面元素不同,复用同一个菜单 ...

  9. HP1020打印机“传递给系统调用的数据区域太小” 如何处理?

    如果电脑上曾经安装过 HP LaserJet 激光打印机的驱动程序,重新安装驱动程序之前,需要完全卸载以前安装的驱动程序,否则可能会出现无法找到设备或者安装不上驱动程序的现象. 安装网站下载的即插即用 ...

随机推荐

  1. Java 内存模型及GC原理 (转载)

    一个优秀Java程序员,必须了解Java内存模型.GC工作原理,以及如何优化GC的性能.与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能 ...

  2. Win 7 IE11不能下载文件,右键另存为也不行

    在IE11中不能下载文件,右键另存为也无效. 发现 在IE11中点击“INTERNET选项”后,IE临时文件夹的地址没有显示,大小为0,修改只能让设置在8-8MB,注销再登录后,一切设置无效. 问题就 ...

  3. C++中的成员对象

    原文链接: http://blog.csdn.net/rhzwan123/article/details/2105205 [概念] 成员对象:当一个类的成员是另一个类的对象时,这个对象就叫成员对象.概 ...

  4. Appium 脚本代码中启动appium server

    import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.service.local.Appiu ...

  5. Java实现打印功能

    用java实现打印,java.awt中提供了一些打印的API,要实现打印,首先要获得打印对象,然后继承Printable实现接口方法print,以便打印机进行打印,最后用Graphics2D直接输出直 ...

  6. 关于java代码提交HTTP POST请求中文乱码的解决方法

    首先说明下这些只是根据我工作常用经验的总结,可能不一定完全对,也不一定全面,但却是最通用的. JAVA里HTTP提交方式 httpurlconnection:jdk里自带的 httpclient:ap ...

  7. ASP.NET MVC做的微信WEBAPP中调用微信JSSDK扫一扫

    今天做一个项目,是在微信上用的,微信WEB APP,里面用到了调用手机摄像头扫一扫二维码的功能,记得以前某个项目里写有的,但是找不到之前那个项目源码了,想复制粘贴也复制不了了,只好对着微信的那个开发文 ...

  8. Objective-c在宏里拼接字符串

    //正式服务器#define API_DOMAIN @"www.online.com"//测试服务器//#define DOMAINXX @"192.168.0.10&q ...

  9. IOS 学习 Key-value coding

    1 前言 本节我们主要介绍键值编码,以及如何使一个类符合KVC编码. 2 详述 键-值编码是一个对于间接访问一个对象属性和关系使用字符标识的机制.它支持或者关系几个特别的Cocoa编程机制和技术,在C ...

  10. 关于casperjs的介绍

    casperjs是一个自动化测试框架,功能强大,也很适合当做爬虫软件使用,casperjs基于phantomjs软件,phantomjs是一个没有界面的浏览器环境,基于python环境 一,安装cas ...