最近项目开发过程中遇到了一个问题,自己用ContextMenu创建了右键菜单后,弹出的右键菜单,不管是左击还是右击都是有效的,这显然不符合人们的使用习惯,查了很久的资料,终于解决了这个问题。话不多说,直接上核心部分代码。
public bool IsMouseLeftButtonDown =false; //判断鼠标是否按下的标志private static ContextMenu CreatContextMenu_ForNormalButton(uint controlId){ //创建一个右键菜单 ContextMenu contextMenu = new ContextMenu() { Name = "contextMenu" }; //将右键菜单进行绑定 setContextMenu(contextMenu); //创建子菜单项 MenuItem TestItem = new MenuItem() { Name = "MouseLeftButtonDownValid" }; TestItem.SetResourceReference(MenuItem.HeaderProperty, "Str_MouseLeftButtonDownValid"); TestItem.CommandParameter = string.Format("{0}:0x{1:X8}", MouseLeftButtonDownValid,controlId); TestItem.Command = MyRelayCommand; /*注意 这里为子菜单项添加鼠标右键按下事件,一定是PreviewMouseDown,mouseDown不能进入到MenuItem_MouseDown函数,至于为什么要这样,文章后面有说明*/ TestItem.PreviewMouseDown += new MouseButtonEventHandler(MenuItem_MouseDown); //TestItem.MouseDown += new MouseButtonEventHandler(MenuItem_MouseDown); //将子菜单项添加到右键菜单中 contextMenu.Items.Add(TestItem); return contextMenu;}//绑定右键菜单private static void setContextMenu(ContextMenu menu){ Binding bind = new Binding(); bind.RelativeSource = new RelativeSource(RelativeSourceMode.Self); bind.Path = new System.Windows.PropertyPath("PlacementTarget"); menu.SetBinding(ContextMenu.DataContextProperty, bind);}//RelayCommand命令public RelayCommand MyRelayCommand{ get { if (null == this.operateDevice_RelayCommand) { this.operateDevice_RelayCommand = new RelayCommand(x => this.operateDevice(x), x => this.canOperateDevice(x)); } return this.operateDevice_RelayCommand; }}//鼠标右键按下的判断函数private static void MenuItem_MouseDown(object sender, MouseButtonEventArgs e){ if (e.LeftButton == MouseButtonState.Pressed) { IsMouseLeftButtonDown = true; //左键按下有效 } else { IsMouseLeftButtonDown = false; //右键按下无效 }}
然后通过IsMouseLeftButtonDown这个标志去RelayCommand中的命令执行函数operateDevice中去判断操作是否可以执行,便可以解决这个问题。这里说明PreviewMouseDown与MouseDown的区别:PreviewMouseDown 对应的冒泡事件为 MouseDown 。两者区别是,冒泡关系(或叫触发的先后顺序)。当鼠标按下,先触发PreviewMouseDown,然后,阻止MouseDown的触发(或叫阻止事件传递,或叫停止冒泡),所以可以将PreviewMouseDown视为MouseDown的过滤器(或叫必经之路),通常你可以在PreviewMouseDown中做一些预先处理,为MouseDown做铺垫。或者做一些逻辑判断,以决定是否要触发MouseDown,等等之类,看你的需要而定。
希望对各位正在做C#前端开发的同仁们有用。
参考文献:
联系客服