在父母之后WPF MenuItem.Click中断

我试图用各种MenuItems(所有在代码中创建)动态填充Menu控件(它驻留在ControlTemplate中),但我遇到了一些奇怪的问题.如果MenuItems都是作为根项创建的,则它们会成功触发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中预先定义菜单并在XAML中设置所有Click事件,它可以完美地工作 – 但它必须在代码中,所以这不是一个选项.此外,如果我让’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:

我在一个干净的项目中复制了原始帖子中的所有内容,而且一切都很完美.因此,菜单或MenuItems或它们的使用方式不是问题.这个问题的原因还不得而知……

编辑3:

根据要求,我使用添加到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");
});

单击“死”MenuItems时,总是会触发PreviewMouseLeftButtonDown.他们的Click事件在成为父母之后继续停止工作.仍然没有解决方案也没有问题的迹象……

编辑4:

我做了以下测试,为L1和L2添加了以下代码:

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

单击时,MenuItem L1和L2都响应PreviewMouseLeftButtonDown,但在作为父级后继续停止响应Click.

最佳答案 我终于解开了这个谜团.我在其中发现任何点击后,向父控制窃取焦点追踪问题,尽管奇怪的是菜单保持打开并对导航作出反应,即使它没有焦点.一切似乎都与Focus()被删除的调用一起工作.

发生的事情的细节:

没有MenuItem育儿:

1)我点击一个根MenuItem,它响应Click.

2)然后父母拦截OnPreviewMouseDown并调用Focus().

由于Click成功触发,因此在这种情况下失去焦点不会导致任何不良后果.

WITH MenuItem为父母:

1)我点击菜单然后打开.

2)然后父母拦截OnPreviewMouseDown并调用Focus().

3)菜单保持打开状态并继续对导航作出反应(这是否意味着发生?).

4)当我在任何MenuItem上第二次点击进行选择时,菜单最终意识到它失去了焦点并关闭 – 同时也丢弃了点击.

然后它似乎是由ClickItem制作并丢弃点击…导致原始帖子中遇到的问题.

点赞