MenuItem事件被多次调用 [英] MenuItem event called multiple times

查看:54
本文介绍了MenuItem事件被多次调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读了xml课:

public class MenuItem
{
  public string Header{get;set;}
  public List<MenuItem> ChildMenuItems{get;set;}
}

我明白了

  • 菜单1
    • 菜单1.1
    • 菜单1.2
      • 菜单1.2.1
      • 菜单1.2.2
      • 菜单2.1
      • 菜单2.2

      然后在MenuViewModel中设置列表

      Then set list in MenuViewModel

       MenuItems = new ObservableCollection<MenuItem>(Service.GetMenu());
      

      然后在UserControl中为caliburn Message.Attach和Action.TargetWithoutContext设置属性

      And in UserControl set properites for caliburn Message.Attach and Action.TargetWithoutContext

      <Setter Property="cal:Message.Attach" Value="[Event Click] = [Action MenuClick($originalsourcecontext)]" />
      <Setter Property="cal:Action.TargetWithoutContext" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
      

      有时有时会多次调用方法"MenuClick":

      如果我单击菜单1-> MenuClick被执行1次
      如果我单击菜单1.1-> MenuClick被执行2次
      如果单击菜单1.2.1-> MenuClick,将执行3次

      Method "MenuClick" is sometimes called more times then expected:

      If I Click Menu 1 -> MenuClick is executed 1 time
      If I Click Menu 1.1 -> MenuClick is executed 2 times
      If I Click Menu 1.2.1 -> MenuClick is executed 3 times

      但是我希望菜单1.1和菜单1.2.1事件仅被调用一次.
      有什么主意吗?

      But I would like that Menu 1.1 and Menu 1.2.1 events are called only once.
      Any idea?

      推荐答案

      不确定为什么会发生这种情况,但这可能与事件冒泡有关.

      Not sure why this happens but it's probably something to do with event bubbling.

      当您单击顶部菜单项时,不会发送操作消息.仅在菜单关闭时才会触发操作消息.

      When you click on the top menu item the action message isn't dispatched. It's only when the menu closes that the action message fires.

      如果要避免这种情况,只需查看 RoutedEventArgs 并检查 OriginalSource 是否与 ActionExecutionContext.Source 匹配.

      If you want to avoid this, you can simply look at the RoutedEventArgs and check that the OriginalSource matches ActionExecutionContext.Source.

      例如

      public void MenuClick(ActionExecutionContext context)
      {
          var routed = context.EventArgs as RoutedEventArgs;
      
          if(routed == null)
              throw new Exception("No routed event");
      
          if (routed.OriginalSource == context.Source)
          {
              MessageBox.Show(((MenuItem)context.Source).Header.ToString());
          }
      }
      

      免责声明:这样做可能更容易

      Disclaimer: There may be a much easier way of doing this

      更新:

      好的,将路由事件标记为已处理会阻止它冒泡,所以这与冒泡有关-我只是使用下面的代码来停止事件在树上的传播.

      Ok marking the routed event as handled stops it bubbling so it is something to do with bubbling - I'd just use the below code to stop the event propagating any further up the tree

      public void MenuClick(ActionExecutionContext context)
      {
          var routed = context.EventArgs as RoutedEventArgs;
      
          if (routed != null)
              routed.Handled = true;
      
           MessageBox.Show(((MenuItem) context.Source).Header.ToString());
      }
      

      这篇关于MenuItem事件被多次调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆