WPF自定义路由事件一般3个步骤
1.注册路由事件
2.路由事件包装
3.定义触发事件的方法
public class myButton:Button { //1.定义并注册事件 public static readonly RoutedEvent TimeEvent = EventManager.RegisterRoutedEvent("GetTime", RoutingStrategy.Bubble, typeof(EventHandler<TimeRoutedEventArgs>), typeof(myButton)); //2.包装事件 public event EventHandler GetTime { add { this.AddHandler(TimeEvent, value); } remove { this.RemoveHandler(TimeEvent, value); } } //3.激发事件 protected override void OnClick() { base.OnClick(); TimeRoutedEventArgs args = new TimeRoutedEventArgs(TimeEvent, this); args.ClickTime = DateTime.Now; this.RaiseEvent(args); } }
这里需要注意的是EventManager.RegisterRoutedEvent方法的第三个参数,委托有EventHandler和RoutedEventHandler,看它们的定义,发现EventHandler可以带一个自定义的消息参数
// 摘要: // 表示将处理事件的方法。 // // 参数: // sender: // 事件源。 // // e: // 一个包含事件数据的 System.EventArgs。 // // 类型参数: // TEventArgs: // 由该事件生成的事件数据的类型。 [Serializable] public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
而RoutedEventHandler只能严格按照委托类型来定义
// 摘要: // 表示将处理各种路由事件的方法,这些路由事件不包含除所有路由事件共有数据之外的其他特定事件数据。 // // 参数: // sender: // 附加此事件处理程序的对象。 // // e: // 事件数据。 public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);
表面上的区别就在这里,如果你的路由事件需要自定义消息参数,那么就选择EventHandler,再深一点的区别,那么还请前辈们告知。
定义好路由事件之后,只需要在订阅者加入侦听即可
<Grid x:Name="grid1" local:myButton.GetTime="myButton_GetTime_1"> <Grid x:Name="grid2" local:myButton.GetTime="myButton_GetTime_1"> <Grid x:Name="grid3" local:myButton.GetTime="myButton_GetTime_1"> <ListBox x:Name="lb"></ListBox> <local:myButton Width="100" Height="100" Content="Hello" GetTime="myButton_GetTime_1"></local:myButton> </Grid> </Grid> </Grid>