Avalon学习笔记 之 路由事件
2005-07-12 23:09 Colin Han 阅读(2279) 评论(0) 编辑 收藏 举报
Avalon中又一个非常吸引人的功能——路由事件(Routed Event).
在某些概念上和附加属性有些类似。
概述
Avalon提供了一套事件路由技术,从而我们可以在父节点上接收和处理子节点的事件。
下图是路由事件的会意图。
微软定义了两种路由事件,分别称为深入(Tunneling)事件和冒出(Bubbling)(附:微软还定义了一种直接(Direct)事件,个人认为不能称之为路由事件)
对于深入事件,事件先由根节点进行处理,然后交由子节点处理,一级一级向下传,直到驱动这个事件的对象(如图Tunnel路径)。而冒出事件则正向反,现有驱动这个事件的对象处理,然后依次向上传递,直到根节点最后处理(相应的,直接事件只交由驱动这个事件的对象处理,不进行传递)。在整个处理路由的任何一个环节,都可以阻止这个事件的继续传递。
路由事件的事件参数必须从RoutedEventArgs继承,这个参数中包含一个属性Handled,事件处理函数可以通过将这个参数置为True而阻止路由事件的继续传递。
一个包含路由事件的对象的例子:
定义路由事件
必须使用EventManager.RegisterRoutedEvent注册一个路由事件
将它保存在一个只读静态成员中是为了将来更加容易的使用它。红色的部分声明这个路由事件的类型。例子中我们声明了一个冒出事件。
触发路由事件
为了使用它的路由功能,我们不能再使用传统的调用事件处理函数的逻辑,而必须使用下面的逻辑:
XAML:
捕获子节点上的事件采用下面的语法:
C#:
XAML:
在某些概念上和附加属性有些类似。
概述
Avalon提供了一套事件路由技术,从而我们可以在父节点上接收和处理子节点的事件。
下图是路由事件的会意图。
微软定义了两种路由事件,分别称为深入(Tunneling)事件和冒出(Bubbling)(附:微软还定义了一种直接(Direct)事件,个人认为不能称之为路由事件)
对于深入事件,事件先由根节点进行处理,然后交由子节点处理,一级一级向下传,直到驱动这个事件的对象(如图Tunnel路径)。而冒出事件则正向反,现有驱动这个事件的对象处理,然后依次向上传递,直到根节点最后处理(相应的,直接事件只交由驱动这个事件的对象处理,不进行传递)。在整个处理路由的任何一个环节,都可以阻止这个事件的继续传递。
路由事件的事件参数必须从RoutedEventArgs继承,这个参数中包含一个属性Handled,事件处理函数可以通过将这个参数置为True而阻止路由事件的继续传递。
一个包含路由事件的对象的例子:
public class MyButtonSimple: Button
{
// Create a custom routed event by first registering a RoutedEvent
// This event uses the bubbling routing strategy
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent("Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));
// Provide CLR accessors for the event
public event RoutedEventHandler Tap
{
add { AddHandler(TapEvent, value); }
remove { RemoveHandler(TapEvent, value); }
}
// This virtual method raises the Tap event
protected virtual void OnTap()
{
RoutedEventArgs newEvent = new RoutedEventArgs();
newEvent.RoutedEvent = MyButtonSimple.TapEvent;
RaiseEvent(newEvent);
}
// For demonstration purposes we raise the event when the MyButtonSimple is clicked
protected override void OnClick()
{
OnTap();
}
}
{
// Create a custom routed event by first registering a RoutedEvent
// This event uses the bubbling routing strategy
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent("Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));
// Provide CLR accessors for the event
public event RoutedEventHandler Tap
{
add { AddHandler(TapEvent, value); }
remove { RemoveHandler(TapEvent, value); }
}
// This virtual method raises the Tap event
protected virtual void OnTap()
{
RoutedEventArgs newEvent = new RoutedEventArgs();
newEvent.RoutedEvent = MyButtonSimple.TapEvent;
RaiseEvent(newEvent);
}
// For demonstration purposes we raise the event when the MyButtonSimple is clicked
protected override void OnClick()
{
OnTap();
}
}
定义路由事件
必须使用EventManager.RegisterRoutedEvent注册一个路由事件
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent("Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));
触发路由事件
为了使用它的路由功能,我们不能再使用传统的调用事件处理函数的逻辑,而必须使用下面的逻辑:
RoutedEventArgs newEvent = new RoutedEventArgs();
newEvent.RoutedEvent = MyButtonSimple.TapEvent;
RaiseEvent(newEvent);
newEvent.RoutedEvent = MyButtonSimple.TapEvent;
RaiseEvent(newEvent);
来驱动这个事件。
捕获事件
捕获路由事件分为两种情况,捕获本身的事件 和 捕获子节点的事件。
捕获本身的事件和传统的Windows应用一样的。下面是它们的语法:
C#:
MyButtonSimple button = new MyButtonSimple();
button.Tap += new RoutedEventHandler(HandlerFunction);
button.Tap += new RoutedEventHandler(HandlerFunction);
<MyButtonSimple Tap="HandlerFunction">button1</MyButtonSimple>
捕获子节点上的事件采用下面的语法:
C#:
ButtonContainer.AddHandler(MyButtonSimple.TapEvent, new RoutedEventHandler(HandlerFunction));
<StackPanel Name="ButtonContainer" Button.Click="HandlerFunction">