多次调用 MenuItem 事件
MenuItem event called multiple times
我读 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 中为 caliburn 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" 有时被调用的次数比预期的要多:
如果我点击 Menu 1 -> MenuClick 执行 1 次
如果我点击 Menu 1.1 -> MenuClick 执行 2 次
如果我点击 Menu 1.2.1 -> MenuClick 被执行了 3 次
但我希望 Menu 1.1 和 Menu 1.2.1 事件只被调用一次。
有什么想法吗?
不确定为什么会发生这种情况,但可能与事件冒泡有关。
当您单击顶部菜单项时,不会发送操作消息。只有当菜单关闭时才会触发操作消息。
如果您想避免这种情况,只需查看 RoutedEventArgs
并检查 OriginalSource
是否匹配 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());
}
}
免责声明:可能有更简单的方法
更新:
好的,将路由事件标记为已处理会阻止它冒泡,所以它与冒泡有关 - 我只是使用下面的代码来阻止事件在树上进一步传播
public void MenuClick(ActionExecutionContext context)
{
var routed = context.EventArgs as RoutedEventArgs;
if (routed != null)
routed.Handled = true;
MessageBox.Show(((MenuItem) context.Source).Header.ToString());
}
我读 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 中为 caliburn 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" 有时被调用的次数比预期的要多:
如果我点击 Menu 1 -> MenuClick 执行 1 次
如果我点击 Menu 1.1 -> MenuClick 执行 2 次
如果我点击 Menu 1.2.1 -> MenuClick 被执行了 3 次
但我希望 Menu 1.1 和 Menu 1.2.1 事件只被调用一次。
有什么想法吗?
不确定为什么会发生这种情况,但可能与事件冒泡有关。
当您单击顶部菜单项时,不会发送操作消息。只有当菜单关闭时才会触发操作消息。
如果您想避免这种情况,只需查看 RoutedEventArgs
并检查 OriginalSource
是否匹配 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());
}
}
免责声明:可能有更简单的方法
更新:
好的,将路由事件标记为已处理会阻止它冒泡,所以它与冒泡有关 - 我只是使用下面的代码来阻止事件在树上进一步传播
public void MenuClick(ActionExecutionContext context)
{
var routed = context.EventArgs as RoutedEventArgs;
if (routed != null)
routed.Handled = true;
MessageBox.Show(((MenuItem) context.Source).Header.ToString());
}