【WPF】右键菜单ContextMenu可点击区域太小的问题

简介: 原文:【WPF】右键菜单ContextMenu可点击区域太小的问题问题描述 正常使用右键菜单ContextMenu时,如果菜单项是不变的,可以直接在XAML中写死,如下是给一个Button按钮添加了右键菜单功能。
原文: 【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 = "12", Age = 10});
DataList.Add(new Student() { Num = "12213", Age = 10 });
DataList.Add(new Student() { Num = "1212", Age = 10 });
DataList.Add(new Student() { Num = "2", Age = 10 });
DataList.Add(new Student() { Num = "112341242134122", Age = 10 });
DataList.Add(new Student() { Num = "123452342", Age = 10 });

运行后即可发现问题。

仔细观察上图运行效果,每个菜单项是嵌套在条目内部的,只有点击到中间深色区域才能触发菜单项的点击事件!点击左右两端浅色部分也能使菜单项关闭,但不会触发菜单项的点击事件!

 

解决方案

最初的想法是给内部被嵌套的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菜单项覆盖了整个条目,且点击左右两端都能触发点击事件了!

 

目录
相关文章
|
C#
WPF 左键单击弹出菜单 ContextMenu
原文:WPF 左键单击弹出菜单 ContextMenu WPF中的ContextMenu在XAML中可直接做出来,但是仅限于右键弹出菜单,如果需要添加左键弹出功能,只需要在事件中添加Click事件 XMAL代码如下 ...
2809 0
|
数据可视化 C# DataX
WPF 的 ElementName 在 ContextMenu 中无法绑定成功?试试使用 x:Reference!
原文:WPF 的 ElementName 在 ContextMenu 中无法绑定成功?试试使用 x:Reference! 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
1228 0
|
前端开发 C#
WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参
原文:WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参 ContextMenu无论定义在.cs或.xaml文件中,都不继承父级的DataContext,所以如果要绑定父级的DataContext,直接DataContext=“{Bind...
3290 0
|
C#
WPF ContextMenu的使用
给ContextMenu菜单添加图片 ...
1044 0
|
1月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
150 0
|
1月前
|
C#
浅谈WPF之装饰器实现控件锚点
使用过visio的都知道,在绘制流程图时,当选择或鼠标移动到控件时,都会在控件的四周出现锚点,以便于修改大小,移动位置,或连接线等,那此功能是如何实现的呢?在WPF开发中,想要在控件四周实现锚点,可以通过装饰器来实现,今天通过一个简单的小例子,简述如何在WPF开发中,应用装饰器,仅供学习分享使用,如有不足之处,还请指正。
84 1
|
10月前
|
C# Windows
WPF技术之图形系列Polygon控件
WPF Polygon是Windows Presentation Foundation (WPF)框架中的一个标记元素,用于绘制多边形形状。它可以通过设置多个点的坐标来定义多边形的形状,可以绘制任意复杂度的多边形。
577 0
|
10月前
|
C# Windows
WPF技术之RichTextBox控件
WPF RichTextBox是Windows Presentation Foundation (WPF)中提供的一个强大的文本编辑控件,它可以显示富文本格式的文本,支持多种文本处理操作。
397 0
|
1月前
|
前端开发 C# 容器
浅谈WPF之控件拖拽与拖动
使用过office的visio软件画图的小伙伴都知道,画图软件分为两部分,左侧图形库,存放各种图标,右侧是一个画布,将左侧图形库的图标控件拖拽到右侧画布,就会生成一个新的控件,并且可以自由拖动。那如何在WPF程序中,实现类似的功能呢?今天就以一个简单的小例子,简述如何在WPF中实现控件的拖拽和拖动,仅供学习分享使用,如有不足之处,还请指正。
135 2
|
10月前
|
数据挖掘 数据处理 C#
WPF技术之DataGrid控件
WPF DataGrid是一种可以显示和编辑数据的界面控件。它可以作为表格形式展示数据,支持添加、删除、修改、排序和分组操作。
218 0