最近项目开发过程中遇到了一个问题,自己用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; //右键按下无效
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
然后通过IsMouseLeftButtonDown这个标志去RelayCommand中的命令执行函数operateDevice中去判断操作是否可以执行,便可以解决这个问题。这里说明PreviewMouseDown与MouseDown的区别:PreviewMouseDown 对应的冒泡事件为 MouseDown 。两者区别是,冒泡关系(或叫触发的先后顺序)。当鼠标按下,先触发PreviewMouseDown,然后,阻止MouseDown的触发(或叫阻止事件传递,或叫停止冒泡),所以可以将PreviewMouseDown视为MouseDown的过滤器(或叫必经之路),通常你可以在PreviewMouseDown中做一些预先处理,为MouseDown做铺垫。或者做一些逻辑判断,以决定是否要触发MouseDown,等等之类,看你的需要而定。
希望对各位正在做C#前端开发的同仁们有用。
参考文献:
|