在具体做一些项目的时候,有时候需要需要先左键点击某个节点,然后再右键点击节点的时候才弹出右键菜单,所以直接右键点击时需要禁用掉右键菜单,这里比如我们为Grid添加了ContextMenu,但是我们需要设置一个bool型的变量isSelected,当我们执行到MouseLeftButtonDown事件中的时候,我们就可以将isSelected设置为true,然后在Grid中添加PreviewMouseRightButtonUp="OnMouseRightButtonUp"(隧道事件路由)事件或者是MouseRightButtonUp(冒泡事件路由)事件,在本项目中两者都可以,但是不要添加在及其子节点下面,这个稍后会介绍,然后在主程序中执行下面的代码:

private void OnMouseRightButtonUp(object sender,MouseButtonEventArgs e)

{

if(isSelected==true)

{

//使消息可以传递

e.Handled=false;

}

else

{

e.Handled=true;

}

isSelected=false;

}

这样当我们先左键点击某一个节点的时候,然后再点击右键的时候才能弹出ContextMenu,这里我们需要正确理解Handled的含义,Handled将路由事件标记为已处理的值。如果 Handled 的值为 true,则可以防止事件路由路径上的大多数处理程序再次处理同一事件。这在实际的事件处理中是非常有用的,因为WPF的这种层层嵌套的UI设计思想,使得某一个事件,例如UIElement.MouseLeftButtonDown在很多元素上都会触发,根据事件的不同类型,可以有冒泡触发或者是隧道的这种方式来触发,但事实上只有一个元素最终执行该事件,如果某一个元素已经执行过该事件,那么它就会将Handled 的值设为 true,这样事件就不会向下或者向上路由了,如果想让事件继续路由就要将Handled设置为false这个是非常重要的,下面的内容参考一下别人写的一篇博客,很有意义。

在读《WPF高级编程》,看到事件的上传和下传。有个例子:

前台代码:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Window1" >

PreviewMouseLeftButtonDown="Grid_PreviewMouseLeftButtonDown"

Width="313" Height="271" Name="mygrid">

MouseLeftButtonDown="Button_MouseLeftButtonDown" Click="Button_Click" Name="btnGo">

MouseLeftButtonDown="textBox1_MouseLeftButtonDown"

PreviewMouseLeftButtonDown="textBox1_PreviewMouseLeftButtonDown">

分别为Grid,Button,TextBox定义了PreviewMouseLeftButtonDown和MouseLeftButtonDown事件,并且为Button定义的Click事件。

后台代码如下:

public partial class Window1 : Window

{

public Window1()

{

InitializeComponent();

}

private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

Debug.WriteLine("Grid_PreviewMouseLeftButtonDown");

}

private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

Debug.WriteLine("Button_PreviewMouseLeftButtonDown");

}

private void textBox1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

Debug.WriteLine("textBox1_PreviewMouseLeftButtonDown");

}

private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

Debug.WriteLine("Grid_MouseLeftButtonDown");

}

private void Button_Click(object sender, RoutedEventArgs e)

{

Debug.WriteLine("Button_Click");

}

private void textBox1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

Debug.WriteLine("textBox1_MouseLeftButtonDown");

}

private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

Debug.WriteLine("Button_MouseLeftButtonDown");

}

}

但是在执行的时候,MouseLeftButtonDown事件总是无法触发。查看了一些资料,才知道这是一个设计原则上的问题。控件在捕获了MouseLeftButtonDown事件后,会将该事件的“Handled”设置为True,这个属性是用在事件路由中的,当某个控件得到一个RoutedEvent,就会检测Handled是否为true,为true则忽略该事件。

并且,控件本身的Click事件,相当于将MouseLeftButtonDown事件抑制(Supress)掉了,转换成了Click事件。所以,如果一定要使用这个事件的话,需要在初始化的函数里利用UIElement的AddHandler方法,显式的增加这个事件。

---------方法说明:---------------------------------------------------------------------------------

UIElement.AddHandler 方法 (RoutedEvent, Delegate, Boolean)

为指定的路由事件添加路由事件处理程序,并将该处理程序添加到当前元素的处理程序集合中。将 handledEventsToo 指定为 true 时,可为已标记为由其他元素在事件路由过程中处理的路由事件调用所提供的处理程序。

参数说明:

handledEventsToo类型:System..::.Boolean

如果为 true,则将按以下方式注册处理程序:即使路由事件在其事件数据中标记为已处理,也会调用该处理程序;如果为 false,则使用默认条件注册处理程序,即当路由事件被标记为已处理时,将不调用处理程序。

默认值为 false。

修改后的程序代码如下:

public Window1()

{

InitializeComponent();

mygrid.AddHandler(Grid.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.Grid_MouseLeftButtonDown), true);

btnGo.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.Button_MouseLeftButtonDown), true);

textBox1.AddHandler(TextBox.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.textBox1_MouseLeftButtonDown), true);

}

再次运行,调用成功,事件的执行顺序是:

次序

控件

事件

事件类型

1

Grid

PreviewMouseLeftButtonDown

下传

2

Button

PreviewMouseLeftButtonDown

下传

3

TextBox

PreviewMouseLeftButtonDown

下传

4

TextBox

MouseLeftButtonDown

上传

5

Button

MouseLeftButtonDown

上传

6

Grid

MouseLeftButtonDown

上传

如果点击Button,则事件的执行顺序是:

次序

控件

事件

事件类型

1

Grid

PreviewMouseLeftButtonDown

下传

2

Button

PreviewMouseLeftButtonDown

下传

3

Button

MouseLeftButtonDown

上传

4

Grid

MouseLeftButtonDown

上传

5

Button

Click

最后补充一点:

在事件处理程序中,可以取消事件处理,查找事件的源元素

例如在下面的代码中:

private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

Debug.WriteLine("Button_PreviewMouseLeftButtonDown");

// e.Handled = true;

// Button myButton = e.Source as Button;

}

1.取消事件处理:  设置 e.Handled = true;

2.在事件处理程序中查找源元素:  e.Source 传递一个实际对象实例,可以将其强制转换为System.Windows.Controls.Button类型,通过这个变量,可以访问这个控件提供的所有本地属性,方法和事件。

wpf 代码获取contextmenu_WPF 如何控制右键菜单ContextMenu的弹出相关推荐

  1. Winform知识扩展-------右键菜单与InputBox弹出式输入框

    一.右键菜单 右键菜单,winform控件ContextMenuStrip,即上下文菜单 下面举例在ListBox控件中点击右键,出现上下文菜单: 1. 准备好一个ListBox和里面的数据: 2.从 ...

  2. wpf 代码获取contextmenu_wpf – 如何在动态创建的ContextMenu中添加水平分隔符?

    我在互联网上寻找解决方案,但在我的样品中找不到.我需要在从后面的代码生成的上下文菜单项之间添加一个分隔符.我试图添加如下代码行,但没有成功. this.Commands.Add(new ToolStr ...

  3. wpf 代码获取contextmenu_[C#] 转:在WPF里面获取右键弹出菜单(ContextMenu)的鼠标点击源(Owner)控件...

    WPF的ContextMenu没有类似WinForm里面ContextMenu.SourceControl的概念,但是你可以通过ContextMenuService的GetPlacementTarge ...

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

    [WPF]右键菜单ContextMenu可点击区域太小的问题 原文:[WPF]右键菜单ContextMenu可点击区域太小的问题 问题描述 正常使用右键菜单ContextMenu时,如果菜单项是不变的 ...

  5. 纵向、横向导航菜单及二级弹出菜单

    一.纵向导航菜单及二级弹出菜单 首先在body中添加一个div标签,其中包含ulli ul的标签结构存放网站菜单,效果如下: <%@ page language="java" ...

  6. SAP QM 事务代码QE01录入结果后回车,为啥不弹出Manual Valuation窗口?

    SAP QM 事务代码QE01录入结果后回车,为啥不弹出Manual Valuation窗口? 执行事务代码QE01为检验批#10000000476录入结果, 录入检验结果后回车,没有弹出类似如下图的 ...

  7. WPF中的右键菜单ContextMenu

    WPF中的右键菜单主要是通过ContextMenu来实现,ContextMenu的使用有两种方式 一..在Resources中声明,在控件中使用. 1.在Resources中添加ContextMenu ...

  8. jqGrid 右键菜单contextmenu简单实现

    鼠标右键单击表格弹出快捷菜单可以查看.编辑.新增.删除行记录,这是很多项目的常见操作,jqGrid也可以实现类似功能,本案例依赖:bootstrap-contextmenu,该项目比较老了作者已经不维 ...

  9. java 树 右键菜单_VUE实现Studio管理后台(八):用右键菜单contextmenu,编辑树形结构...

    RXEdior预设会有文件管理功能,但是灵活性需求不大,目前的设想是文件夹不允许修改,只允许增删改文件.基于这样的设想,把界面实现成这个效果: 这个功能并不是一个通用功能,并且我们做的代码,也没有按照 ...

最新文章

  1. 008_Gson从序列化中排除字段
  2. [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
  3. Happy Necklace dp 递推 矩阵快速幂
  4. 20211126 为什么转动惯量矩阵是正定的?
  5. 中科大 计算机网络3 网络边缘Edge
  6. 如何直观的看出主题模型学习结果的好坏
  7. windows程序窗体创建流程模型A--发送自定义消息逻辑上出现Bug
  8. windows程序窗体创建流程模型A--利用基本数据类型
  9. Python对MySQL数据库的创建,增删改查操作
  10. 1.4.2 真正的建造者模式(3.2)
  11. uniapp编译成小程序代码过大的处理方法
  12. Exploratory Data Analysis可视化分析美国天气
  13. Codeforces Round #499 (Div. 2) 1011 C. Fly 二分
  14. 量子计算机的相干特征,几乎不受损耗和退相干影响的量子态,旨在推动量子计算机发展!...
  15. 如何根据边长数值计算六边形的面积
  16. 强化学习-学习笔记11 | 解决高估问题
  17. 一篇文章让你了解大数据挖掘技术
  18. linux双击运行jar包,linux下发布JAR包 并运行
  19. 安卓内部存储之数据库存储
  20. 【历史上的今天】12 月 14 日:计算复杂性理论先驱出生;雅虎群组被关闭;W3C 召开第一次会议

热门文章

  1. COdevs 2823 锁妖塔
  2. 描述性物理海洋学--第9-14章学习笔记
  3. 使用tftp工具备份华为、华三、思科交换机配置的方法
  4. PyQt5_QComboBox_实现一个江苏 浙江 安徽 三省市的级联表
  5. pdfbox在pdf的尾部添加数据
  6. 河南工程学院2022级新生周赛(三)题解
  7. iPhone8接连出现充电等问题,问题扩大将被禁上飞机
  8. 如何找回丢失的数码照片
  9. 腾讯云 Finops Crane 开发者集训营 - 让云不再“钱”途无量
  10. 如何检验光盘镜像(ISO格式文件)并刻录系统安装光盘?