通过前一篇 《深入理解WPF路由事件》,了解路由事件的声明、定义、注册/注销,以及触发机制; 其中事件的注册/注册,以及触发方法都是定义在UIElement中的;所以路由事件的宿主一般是可视化的UI控件。 如果是非UIElement派生类,如果要实现路由事件,则需要像附加属性一样,通过附加的方式实现,附加上路由事件 (Attached Event);
附加属性是某对象在特定环境中才具备的属性,所以附加属性是定义在环境中的。 而附加事件,是非UIElement想具备事件路由功能,所以是定义在非UIElemnt中,通过借用附加的UIElement的方法,实现路由事件的注册/注销,触发;
(附加)路由事件定义:
public class User
{
/// <summary>
/// 1)声明和定义路由事件
/// </summary>
public static readonly RoutedEvent NameChangedEvent = EventManager.RegisterRoutedEvent("NameChanged", RoutingStrategy.Bubble,typeof(RoutedEventHandler), typeof(User));
/// <summary>
/// 2)绑定路由事件
/// </summary>
/// <param name="obj"></param>
/// <param name="handler"></param>
public void AddNameChangedEvent(UIElement obj, RoutedEventHandler handler)
{
obj.AddHandler(NameChangedEvent, handler);
}
/// <summary>
/// 解绑路由事件
/// </summary>
/// <param name="obj"></param>
/// <param name="handler"></param>
public void RemoveNameChangedEvent(UIElement obj, RoutedEventHandler handler)
{
obj.RemoveHandler(NameChangedEvent, handler);
}
/// <summary>
/// 3)触发路由事件
/// </summary>
/// <param name="obj"></param>
/// <param name="name"></param>
public void RaiseNameChangedEvent(UIElement obj,String name)
{
RoutedEventArgs args = new RoutedEventArgs(NameChangedEvent, this);
obj.RaiseEvent(args);
}
}
绑定事件处理及触发
public partial class MenuTest2 : Window
{
public MenuTest2()
{
InitializeComponent();
}
private void QuestionTempTool_Loaded(object sender, RoutedEventArgs e)
{
//1)定义对象
User user = new User();
//2)添加事件处理
user.AddNameChangedEvent(this, PrintName);
//3)触发事件
user.RaiseNameChangedEvent(this, "Wjj");
}
private void PrintName(object sender, RoutedEventArgs e)
{
Console.WriteLine("附加事件已触发,在这里处理");
}
}