如何在不引发父事件的情况下为子MenuItem设置单击事件

本文关键字:事件 情况下 MenuItem 单击 设置 | 更新日期: 2023-09-27 18:26:11

我有这个代码:

<Menu IsMainMenu="True">
    <MenuItem Header="Parent" Click="ParentItem_Click" >
        <MenuItem Header="Child" Click="ChildItem_Click">
        </MenuItem>
    </MenuItem>
</Menu>

当我单击子MenuItem时,父MenuItem也将被引发。我不想引发家长事件。

如何在不引发父事件的情况下为子MenuItem设置单击事件

这是具有气泡路由策略的事件的标准行为。您可以在事件处理程序中手动设置eventArgs.Handled = true。请参阅将路由事件标记为已处理,以及类处理

考虑到Click事件没有与PreviewClick这样的隧道事件配对,您可以尝试使用PreviewMouseDown PreviewMousUp隧道事件,看看是否可以将逻辑附加到这些事件。

路由事件策略:

气泡:调用事件源上的事件处理程序。路由的事件然后路由到连续的父元素,直到到达元素树根。大多数路由事件使用冒泡路由策略冒泡路由事件通常用于报告输入或不同控件或其他UI元素的状态变化。

Direct:只有源元素本身才有机会调用处理程序作为响应。这类似于Windows窗体用于事件。但是与标准CLR事件不同,直接路由事件支持类处理(类处理是在下一节中解释),并且可以由EventSetter和事件触发器。

隧道:最初,调用元素树根处的事件处理程序。然后,路由事件通过连续的沿着路由的子元素,指向作为路由事件源(引发路由事件的元素)。隧道路由事件通常作为控件的合成,以便来自合成部件的事件可以被特定于完全控制。WPF中提供的输入事件经常出现实现为隧道/冒泡对。隧道事件也是有时称为预览事件,因为命名用于配对的约定。

当点击被路由时,您可以使用以下代码

private void OnYourMenuItemClicked(object sender, RoutedEventArgs e){
     MenuItem item = e.OriginalSource as MenuItem;
     if(null != item)
     {
         // Handle needed menu item click here
     }

}

我知道这已经有4年半的历史了,但解决方案非常简单(我刚刚想出来)。只需说出物品的名称。

XAML

<Menu IsMainMenu="True">
    <MenuItem x:Name="Parent" Header="Parent" Click="ParentItem_Click" >
        <MenuItem x:Name="Child" Header="Child" Click="ChildItem_Click">
        </MenuItem>
    </MenuItem>
</Menu>

代码

private void ParentItem_Click(object sender, RoutedEventArgs e)
{
     MenuItem item = e.OriginalSource as MenuItem;
     if(item == Parent)
     {
         // Handle Parent
     }
}
private void ChildItem_Click(object sender, RoutedEventArgs e)
{
     MenuItem item = e.OriginalSource as MenuItem;
     if(item == Child)
     {
         // Handle Child
     }
}

希望这能帮助到别人!