我有一个资源字典,里面有一个上下文菜单:
<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.WriteLine
和Debug.WriteLine
都会产生输出,但只是“随机”,尤其是当我点击项目底部附近时。某种碰撞检测不起作用?
答案 0 :(得分:40)
ContextMenuOpening事件必须在ContextMenu的祖先上处理,而不是在ContextMenu本身上处理。如果您尝试在ContextMenu上处理它,只有在ContextMenu已经打开时右键单击才会触发事件。
答案 1 :(得分:8)
第一次右键单击时不会触发上下文菜单的打开事件。 它只会在您不移动时进行两次连续右键单击时触发 老鼠。
答案 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>
元素,这是正确的方法并且应该起作用。