WPF MenuItem.Click is interrupted after parenting

I am trying to dynamically populate a Menu control (which is in the ControlTemplate) with various MenuItems (all created in the code), but I am encountering some strange problems. If all MenuItems are created as root elements, they successfully fire the Click event. But as soon as any MenuItem becomes a child of another MenuItem, the parent and child Click events stop firing.

XAML:

<ControlTemplate> <Menu x:Name="MyMenu"/> </ControlTemplate> 

WITH#:

 // 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"); }); } 

The menu is displayed correctly, but none of the pressing events on the sub-items works at all. If I pre-define the menu in XAML and set all the Click events in XAML, it works fine - but it should be in the code, so this is not an option. In addition, if I make β€œL2” a child of β€œMyMenu”, that is, make it the root element, L1 and L2 will start working again, but I cannot have everything as root elements. Is there something I'm missing?

Thanks!

EDIT 1:

I tried a little experiment to make sure everything was properly initialized before bringing up L1-L2 and adding their Click events. Not lucky yet. Here is what I tried:

XAML:

 <ControlTemplate> <Grid> <Menu x:Name="MyMenu"/> <Button x:Name="MyButton"/> </Grid> </ControlTemplate> 

WITH#:

 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"); }); } 

When the window loads and everything is displayed, I click on the button so that the parent event happens and events are added. I see that L2 moves as a child of L1, but when I click either, they do not respond to Click events. If I do not allow a form of parenting to take place, they respond to Click events. I am so confused why this is happening!

EDIT 2:

I reproduced everything from the original post in a clean project, and everything works fine. Therefore, this is not a problem with Menu or MenuItems or the way they were used. The cause of this problem is still unknown ...

EDIT 3:

As requested, I re-tested this by adding the following code to the window:

 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 always starts when a ctrl-click on the "dead" MenuItems. Their Click events continue to shut down after being parented. There is still no solution or indication of the problem ...

EDIT 4:

I performed the following test by adding below code for L1 and L2:

 L1.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(delegate { MessageBox.Show("L1 PreviewMouseLeftButtonDown"); }); // Same for L2 

When Clicked, MenuItem L1 and L2 respond to PreviewMouseLeftButtonDown, but continue to stop responding to Click after being parent.

+4
source share
1 answer

Finally, I solved the secret. I tracked the problem to parental control during the theft of focus after clicks were made in it, although it is strange that the menu remained open and responded to navigation, although it did not have focus. Everything seems to work with a Focus () delete call.

Details of what is happening:

WITHOUT Perception MenuItem:

1) I click on the root element of MenuItem and responds to Click.

2) OnPreviewMouseDown is then intercepted by the parent and the Focus () call is called.

There are no adverse effects caused by loss of focus in this situation, since Click was launched successfully.

WITH Perception MenuItem:

1) I click on the menu and it opens.

2) OnPreviewMouseDown is then intercepted by the parent and the Focus () call is called.

3) The menu remains open and continues to respond to navigation (should this happen?).

4) When I click on any MenuItem a second time to make a selection, the menu finally realizes that it has lost focus and closed - it also rejects the click.

Then it seems that a click has been made and discarded by MenuItem ..., which led to a problem that occurred in the original message.

+2
source

Source: https://habr.com/ru/post/1347264/


All Articles