Я пытаюсь динамически заполнить элемент управления Menu (который находится в шаблоне ControlTemplate) различными MenuItems (все они созданы в коде), но у меня возникают странные проблемы. Если все элементы MenuItem созданы как корневые элементы, они успешно запускают событие Click. Но как только любой MenuItem становится дочерним по отношению к другому MenuItem, события Click родительского и дочернего элементов перестают срабатывать.
XAML:
<ControlTemplate>
<Menu x:Name="MyMenu"/>
</ControlTemplate>
C #:
// This is in the control that the above ControlTemplate is created for
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
MenuItem L1 = new MenuItem() { Header = "L1" };
MyMenu.Items.Add(L1); // Add as root
L1.Click += new RoutedEventHandler(delegate { MessageBox.Show("L1 Click"); });
MenuItem L2 = new MenuItem() { Header = "L2" };
L1.Items.Add(L2); // Add as child of L1.
// Note: If this is a child of MyMenu, both MenuItems work as expected
L2.Click += new RoutedEventHandler(delegate { MessageBox.Show("L2 Click"); });
}
Меню отображается правильно, но ни одно из событий щелчка по подпунктам не срабатывает вообще. Если я предварительно определю меню в XAML и тоже установлю все события Click в XAML, он будет работать отлично - но это должно быть в коде, так что это не вариант. Кроме того, если я сделаю «L2» дочерним по отношению к «MyMenu», то есть вместо этого сделаю его корневым элементом, L1 и L2 снова начнут работать, но я также не могу иметь все в качестве корневых элементов.
Есть что-то, чего мне не хватает?
Спасибо!
РЕДАКТИРОВАТЬ 1:
Я попытался провести небольшой эксперимент, чтобы увидеть, все ли правильно инициализировано, перед тем, как связать L1 с L2 и добавить их события Click. Все еще не повезло. Вот что я попробовал:
XAML:
<ControlTemplate>
<Grid>
<Menu x:Name="MyMenu"/>
<Button x:Name="MyButton"/>
</Grid>
</ControlTemplate>
C #:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
MenuItem L1 = new MenuItem() { Header = "L1" };
MyMenu.Items.Add(L1);
MenuItem L2 = new MenuItem() { Header = "L2" };
MyMenu.Items.Add(L2); // Add this to the menu to make sure it gets initialised
// I created a button so I can make sure that the parenting
// and events are only added after the MenuItems are loaded
MyButton.Click += new RoutedEventHandler(MyButton_Clicked);
}
void MyButton_Clicked(object sender, RoutedEventArgs e)
{
// Note: If these two lines are removed, the events work fine
MyMenu.Items.Remove(L2);
L1.Items.Add(L2);
L1.Click += new RoutedEventHandler(delegate { MessageBox.Show("L1 Click"); });
L2.Click += new RoutedEventHandler(delegate { MessageBox.Show("L2 Click"); });
}
Когда окно загружается и все отображается, я нажимаю кнопку, чтобы произошло родительское воспитание и добавились события. Я вижу, что L2 перемещается как дочерний элемент L1, но когда я нажимаю либо, они не реагируют на события Click. Если я предотвращаю появление родительской формы, они реагируют на события Click. Я так растерялся, почему это происходит!
РЕДАКТИРОВАТЬ 2:
Я воспроизвел все с оригинального поста в чистом проекте, и все это прекрасно работает. Так что это не проблема с Menu или MenuItems или способом их использования. Причина этой проблемы до сих пор неизвестна ...
РЕДАКТИРОВАТЬ 3:
В соответствии с просьбой, я повторно протестировал это с помощью следующего кода, добавленного в окно:
PreviewMouseLeftButtonDown += new MouseButtonEventHandler(delegate
{
// Use Ctrl key to enable MessageBox so focus is not lost when opening menu
if (Keyboard.Modifiers == ModifierKeys.Control)
MessageBox.Show("Window PreviewMouseLeftButtonDown");
});
PreviewMouseLeftButtonDown всегда запускается при нажатии Ctrl на «мертвых» элементах MenuItem. Их события Click по-прежнему перестают работать после рождения До сих пор нет решения, ни указание на проблему ...
РЕДАКТИРОВАТЬ 4:
Я провел следующий тест, добавив приведенный ниже код для L1 и L2:
L1.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(delegate
{
MessageBox.Show("L1 PreviewMouseLeftButtonDown");
});
// Same for L2
При щелчке MenuItem L1 и L2 оба отвечают на PreviewMouseLeftButtonDown, но продолжают перестать отвечать на Click после того, как их родили.