- 创建RoutedEventArgs类的派生类。
public class ReportTimeEventArgs:RoutedEventArgs
{
public ReportTimeEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source)
{}
public DateTime ClickTime { get; set; }
}
- 创建Button类的派生类并添加路由事件
public class TimeButton : Button
{
public static readonly RoutedEvent ReportTimeEvent =
EventManager.RegisterRoutedEvent
("ReportTime", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TimeButton));
public event RoutedEventHandler ReportTime
{
add { this.AddHandler(ReportTimeEvent, value); }
remove { this.RemoveHandler(ReportTimeEvent, value); }
}
protected override void OnClick()
{
base.OnClick(); //保证原有事件发生。
//RoutedEventArgs args = new RoutedEventArgs();
ReportTimeEventArgs args = new ReportTimeEventArgs(ReportTimeEvent, this);
args.ClickTime = DateTime.Now;
this.RaiseEvent(args);
}
}
- 程序界面
<Grid x:Name="grid_1" local:TimeButton.ReportTime="ReportTimeHandler">
<Grid x:Name="grid_2" local:TimeButton.ReportTime="ReportTimeHandler">
<Grid x:Name="grid_3" local:TimeButton.ReportTime="ReportTimeHandler">
<StackPanel x:Name="stackPanel_1" local:TimeButton.ReportTime="ReportTimeHandler">
<ListBox x:Name="listBox" />
<local:TimeButton x:Name="timeButton" Width="80" Height="80"
Content="报时" local:TimeButton.ReportTime="ReportTimeHandler"/>
</StackPanel>
</Grid>
</Grid>
</Grid>
- 对应的后台处理器代码
private void ReportTimeHandler(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
string timeStr = (e as ReportTimeEventArgs).ClickTime.ToLongTimeString();
string content = string.Format("{0} 到达 {1}", timeStr, element.Name);
this.listBox.Items.Add(content);
}
程序运行结果:
我们在注册ReportTimeEvent时使用的时Bubble策略,所以事件是延事件源到元素根来传播的.
- 上面我们在注册路由事件的时候用的是Bubble模式下面我们使用隧道模式即Tunnel。
public static readonly RoutedEvent ReportTimeEvent =
EventManager.RegisterRoutedEvent
("ReportTime", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(TimeButton));
此时的运行结果为:
我们可以发现Tunnel刚好与Bubble策略相反事件的传递路径为:
- 假设我们现在想让事件在某一结点处不在继续传递,我们该怎么做?下面进行介绍:
RoutedEventArgs类或者它的派生类所实例化的对象具有一个bool类型的Handled,当这个属性被设置为true,就会表示路由事件被处理了,路由事件就不会传递了。
- 我们对ReportTimeHandler进行修改
private void ReportTimeHandler(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
string timeStr = (e as ReportTimeEventArgs).ClickTime.ToLongTimeString();
string content = string.Format("{0} 到达 {1}", timeStr, element.Name);
this.listBox.Items.Add(content);
//增加
if(element == this.grid_2)
{
e.Handled = true;
}
}
此时我们用隧道路由继续测试看结果:
到达grid_2就不往下传播了。