问题描述

正常使用右键菜单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. 如何调试makefile变量

    六.七年前写过一篇<跟我一起写Makefile>,直到今天,还有一些朋友问我一些Makefile的问题,老实说,我有一段时间没有用Makefile了,生疏了.回顾,这几年来大家问题我的问题 ...

  2. CTreeCtrl获得鼠标点击时的节点

    原文链接: http://blog.csdn.net/lcalqf/article/details/21321923 1.添加图标 HICON icon[10]; icon[0]=AfxGetApp( ...

  3. nginx访问日志,错误日志参数说明

    说明: nginx日志主要有两种:访问日志.错误日志.其中访问日志记录客户端访问nginx的每一个请求,包含用户地域来源.跳转来源.使用终端.某个URL访问量等信息,访问日志格式可以自定义:错误日志则 ...

  4. Python 文件 isatty() 方法

    概述 Python 文件 isatty() 方法检测文件是否连接到一个终端设备,如果是返回 True,否则返回 False. 语法 isatty() 方法语法如下: fileObject.isatty ...

  5. hibernate显示完整的sql(转)

    不完整的SQL Hibernate: /* insert com.test.bean.User */ insert into user (username, password, email, sex) ...

  6. python 动态属性

    先来看一下一个常见的Python类的定义: class Person(object): name = None age = None def __init__(self,name,age): self ...

  7. Nginx做转发

    二台服务器,服务器A做域名转外,所有外网的域名都到这台服务器A的80端口上,服务器B内网地址192.168.1.227, 上面IIS搭建了N多网站,以端口来区分,用以前的方式 配置转发 结果发现首页能 ...

  8. 2. Apache Axis2 快速学习手册之概览

    这篇博文和大家一起学习下Apache Axis2 官方文档的快速指南篇 英文原文:http://axis.apache.org/axis2/java/core/docs/quickstartguide ...

  9. android 覆盖安装问题

    1.android中覆盖安装不会导致data/data/package下的数据被删除 2.数据库会有数据库的一套升级机制 3.sharepreference 不会被覆盖,如果在app中有使用Key记录 ...

  10. 浅谈HTML5 WebSocket的机制

    回想上一章 在上一章<为什么我们须要HTML5 WebSocket>中,我简单的介绍了下WebSocket的前世今生.相信大家已对WebSocket有了初步的了解.那么今天我们继续深入学习 ...