分享

解决WPF右键菜单的菜单项左击有效右击无效的问题

 牛人的尾巴 2017-12-10

最近项目开发过程中遇到了一个问题,自己用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#前端开发的同仁们有用。

参考文献: 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多