14

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

<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”的定义,并且找不到接受“MyApp.Components.MyContextMenu”类型的第一个参数的扩展方法“ContextMenu_OnContextMenuOpening”(您是否缺少 using 指令或程序集引用?)

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

4

5 回答 5

51

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

于 2013-01-17T10:11:01.380 回答
8

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

第一次右键单击时不会触发上下文菜单的打开事件。仅当您在不移动鼠标的情况下连续两次右键单击时才会触发。

于 2012-05-16T17:19:39.950 回答
8

我相信 kurrazyman 有正确的答案,但我花了一段时间才明白。就我而言,我有一个带有上下文菜单的 TreeView 控件。使用myTreeView.ContextMenu.ContextMenuOpening无效,但使用myTreeView.ContextMenuOpening确实有效。

于 2013-02-21T13:28:54.123 回答
6

它不是错误,它正在工作......这是大多数人对 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>元素,这是正确的方法并且应该可以工作。

于 2019-08-28T13:12:28.147 回答
1

我正在使用IsVisibleChanged事件:

private void ContextMenu_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    var isVisible = (bool)e.NewValue;
    if (isVisible)
    {
        //...
    }
}
于 2012-10-29T14:03:32.407 回答