Событие ContextMenuOpening не запускается в WPF?
У меня есть словарь ресурсов, внутри которого у меня есть контекстное меню:
<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', принимающий можно найти первый аргумент типа "MyApp.Components.MyContextMenu" (вам не хватает директивы using или ссылки на сборку?)
Обновление 2: Похоже, что как Console.WriteLine
, так и Debug.WriteLine
производят вывод, но только "случайно" и особенно когда я нажимаю на нижнюю часть элемента. Может быть, какое-то обнаружение столкновения не работает?
Ответы
Ответ 1
Это ошибка в рамках: http://connect.microsoft.com/VisualStudio/feedback/details/353112/contextmenu-opening-event-doesnt-fire-properly
Событие открытия контекстного меню не запускается при первом щелчке правой кнопкой мыши. Он срабатывает только тогда, когда вы выполняете два последовательных щелчка правой кнопкой мыши, не перемещаясь мышь.
Ответ 2
Событие ContextMenuOpening должно обрабатываться на предком ContextMenu, а не на самом ContextMenu. Если вы попытаетесь обработать его в ContextMenu, событие запускается только при щелчке правой кнопкой мыши, когда ContextMenu уже открыт.
Ответ 3
Я считаю, что курразиман имеет правильный ответ, но мне потребовалось некоторое время, чтобы понять это.
В моем случае у меня был элемент управления TreeView с контекстным меню.
Использование myTreeView.ContextMenu.ContextMenuOpening
не помогло, но с помощью myTreeView.ContextMenuOpening
сделал.
Ответ 4
Я использую IsVisibleChanged:
private void ContextMenu_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var isVisible = (bool)e.NewValue;
if (isVisible)
{
//...
}
}
Ответ 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>
СЦЕНАРИЙ 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>
, который является надлежащим способом сделать это и должен работать.