多次调用MenuItem事件

时间:2015-03-24 13:55:24

标签: wpf c#-4.0 menu caliburn.micro

我读了xml到class:

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
    • 菜单2.1
    • 菜单2.2

然后在MenuViewModel中设置列表

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

在UserControl中设置适用于校准的消息Message.Attach和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 - &gt; MenuClick执行1次
如果我单击菜单1.1 - &gt; MenuClick执行2次
如果我单击菜单1.2.1 - &gt; MenuClick执行3次

但我希望Menu 1.1和Menu 1.2.1事件只被调用一次 有什么想法吗?

1 个答案:

答案 0 :(得分:1)

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

单击顶部菜单项时,不会调度操作消息。只有当菜单关闭时才会触发操作消息。

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

e.g。

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

免责声明:可能有更简单的方法来执行此操作

<强>更新

确定路由事件被处理后停止冒泡它所以它与冒泡有关 - 我只是使用下面的代码来阻止事件在树上向上传播

public void MenuClick(ActionExecutionContext context)
{
    var routed = context.EventArgs as RoutedEventArgs;

    if (routed != null)
        routed.Handled = true;

     MessageBox.Show(((MenuItem) context.Source).Header.ToString());
}