我发现了许多解释冒泡的例子,但没有关于隧道这是关于隧道,例如父母对孩子。我认为我的主要问题是我不明白如何在子节点中注册路由事件(WindowControl到UserControl)。 我得到了:
public partial class MyParent : UserControl
{
public static readonly RoutedEvent RoutedMouseUpEvent = EventManager.RegisterRoutedEvent(
"PreviewMouseLeftButtonUp", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(WindowControl));
// Provide CLR accessors for the event
public event RoutedEventHandler MouseUp
{
add { AddHandler(RoutedMouseUpEvent, value); }
remove { RemoveHandler(RoutedMouseUpEvent, value); }
}
public addView(UserControl view)
{
WindowControl win = new WindowControl();
win.Content = view;
}
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(MyParent.RoutedMouseUpEvent);
RaiseEvent(newEventArgs);
}
}
addView的封装是必要的,应该没问题?通过addView添加子项。 调用Grid_MouseLeftButtonUp 接收器看起来像这样(它是mvvm所以没有太多):
public partial class ChildView : UserControl
{
void UserControl_PreviewMouseLeftButtonUp(object sender, RoutedEventArgs args)
{
int i = 0; // The breakpoint is never called
}
}
xaml中的
<Grid>
<Border BorderBrush="black" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" PreviewMouseLeftButtonUp="UserControl_PreviewMouseLeftButtonUp">
</Border>
</Grid>
如果我忘记了什么,请告诉我。 问题是,路由事件没有到达UserControl_PreviewMouseLeftButtonUp
答案 0 :(得分:11)
这不是隧道路由策略的工作原理。隧道意味着事件将从根开始并沿着树路径向下到达调用控件。例如,如果我们有以下可视树
Window
|
|--> SomeUserControl
|--> MyParent
|
|--> ChildView
然后,如果MyParent
将引发隧道事件,则隧道事件将访问:
和不
总而言之,冒泡事件总是从引发事件的控件开始并停在可视化树的根部,而隧道事件将从可视树的根开始,并在控件上结束事件(确切地说)相同的路径,只有相反的顺序)。
编辑:您可以在MSDN's Routed Events Overview中详细了解路由事件。它还有一个很好的图像证明了这一点: