ContextMenuOpening事件没有在WPF中触发?

Tow*_*wer 12 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">
Run Code Online (Sandbox Code Playgroud)

和资源字典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!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

日志没有出现.我想知道为什么事件没有解雇或到达正确的地方 - 是问题,因为我已经在这个资源字典中包装了上下文菜单?

更新:有趣的是,如果我删除代码隐藏功能,我在编译期间收到错误:

不包含'ContextMenu_OnContextMenuOpening'的定义,并且没有扩展方法'ContextMenu_OnContextMenuOpening'可以找到接受类型'MyApp.Components.MyContextMenu'的第一个参数(你是否缺少using指令或汇编引用?)

更新2:看起来像两个Console.WriteLineDebug.WriteLine产生输出,而只是"随机",特别是当我点击接近该项目的底部.某种碰撞检测可能不起作用?

Ric*_*ner 43

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

  • 究竟.现在你正试图抓住上下文菜单的上下文菜单的开头. (7认同)

Tow*_*wer 10

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

第一次右键单击时不会触发上下文菜单的开启事件.只有在不移动鼠标的情况下进行两次连续右键单击时才会触发.

  • 这不应该标记为答案.这是误导,因为这不是框架中的错误,它按设计工作.kurrazyman的回答是对的. (4认同)

小智 6

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


hsC*_*ode 5

它不是一个错误,它正在工作......这是大多数人在使用 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>
Run Code Online (Sandbox Code Playgroud)

场景 2(这会起作用):

<ListBox Name="lb_sizes" Height="120" ContextMenuOpening="My_ContextMenuOpening">
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"/>
<MenuItem Header="Delete All"/>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

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