ContextMenuOpening事件没有在WPF中触发?

时间:2012-05-16 16:14:16

标签: c# wpf mvvm

我有一个资源字典,里面有一个上下文菜单:

<ResourceDictionary x:Class="MyApp.Components.MyContextMenu"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyApp"
                    xmlns:components="clr-namespace:MyApp.Components">
    <ContextMenu ContextMenuOpening="OnContextMenuOpening">

和资源字典XAML背后有这个代码:

using System;
using System.Windows;
using System.Windows.Controls;

namespace MyApp.Components
{
    public partial class MyContextMenu : ResourceDictionary
    {
        public MyContextMenu()
        {
            InitializeComponent();
        }  

        void OnContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            Console.WriteLine("here i am!");
        }
    }
}

日志未显示。我想知道为什么事件没有触发或到达正确的位置 - 是问题,因为我已将此上下文菜单包装在此资源字典中?

更新:有趣的是,如果删除代码隐藏功能,编译时会出错:

  

不包含'ContextMenu_OnContextMenuOpening'的定义   没有扩展方法'ContextMenu_OnContextMenuOpening'接受a   可以找到类型为“MyApp.Components.MyContextMenu”的第一个参数   (您是否缺少using指令或程序集引用?)

更新2:看起来Console.WriteLineDebug.WriteLine都会产生输出,但只是“随机”,尤其是当我点击项目底部附近时。某种碰撞检测不起作用?

5 个答案:

答案 0 :(得分:40)

ContextMenuOpening事件必须在ContextMenu的祖先上处理,而不是在ContextMenu本身上处理。如果您尝试在ContextMenu上处理它,只有在ContextMenu已经打开时右键单击才会触发事件。

答案 1 :(得分:8)

这是框架中的一个错误:http://connect.microsoft.com/VisualStudio/feedback/details/353112/contextmenu-opening-event-doesnt-fire-properly

  

第一次右键单击时不会触发上下文菜单的打开事件。   它只会在您不移动时进行两次连续右键单击时触发   老鼠。

答案 2 :(得分:6)

我相信kurrazyman有正确的答案,但我花了一段时间来理解它。 在我的例子中,我有一个带有上下文菜单的TreeView控件。 使用myTreeView.ContextMenu.ContextMenuOpening无效,但使用myTreeView.ContextMenuOpening确实无效。

答案 3 :(得分:1)

我改为使用 IsVisibleChanged 事件:

private void ContextMenu_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    var isVisible = (bool)e.NewValue;
    if (isVisible)
    {
        //...
    }
}

答案 4 :(得分:1)

这不是错误,它正在运行...这是大多数人在使用ContextMenuOpening事件时遇到的最常见的错误...请考虑这两种不同的情况以找出此问题的实际原因,

场景1(这将不起作用):

<ListBox Name="lb_sizes" Height="120">
<ListBox.ContextMenu>
<ContextMenu ContextMenuOpening="My_ContextMenuOpening">
<MenuItem Header="Delete"/>
<MenuItem Header="Delete All"/>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>

场景2(这将起作用):

<ListBox Name="lb_sizes" Height="120" ContextMenuOpening="My_ContextMenuOpening">
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"/>
<MenuItem Header="Delete All"/>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>

唯一的区别是将ContextMenuOpening事件分配给适当的元素... 在方案1中,它被分配(附加)到<ContextMenu>元素,在方案2中,它被分配到<ListBox>元素,这是正确的方法并且应该起作用。