?WPF中有两种事件模型:一种是在WinForm时代就存在的CLR事件;另一种是WPF时代的路由事件;
//定义一个委托
public delegate void ClickHandler(String Name);
public class Test
{
/// 定义事件
public event ClickHandler ClickEvent;
/// <summary>
/// 注册事件,事件绑定方法
/// </summary>
/// <param name="handler"></param>
public void RegisterClickEventHandler(ClickHandler handler)
{
ClickEvent += handler;
}
/// 注销事件
public void DeRegisterClickEventHandler(ClickHandler handler)
{
ClickEvent -= handler;
}
/// <summary>
/// 触发事件
/// </summary>
/// <param name="UserName"></param>
public void RaiseClickEvent(string UserName)
{
ClickEvent.BeginInvoke(UserName,null, null);
}
}
public class TestEvent
{
public TestEvent()
{
Test test = new Test();
test.RegisterClickEventHandler(On_Click);
test.RegisterClickEventHandler(On_Click2);
test.RaiseClickEvent("哈哈哈");
}
public void On_Click(String name)
{
Console.WriteLine(name);
}
public void On_Click2(String name)
{
Console.WriteLine(name+name);
}
}
CLR事件特点
1、事件发起者与接收者是紧密关联,不容易解耦
2、如果利用事件传递消息,必须是逐级传递,不比繁琐,也不容易管理;
public delegate void ClickHandler(String Name);
public class Test:UIElement
{
public event ClickHandler ClickEvent;
public void RegisterClickEventHandler(ClickHandler handler)
{
ClickEvent += handler;
}
public void DeRegisterClickEventHandler(ClickHandler handler)
{
ClickEvent -= handler;
}
/// <summary>
/// 定义路由事件
/// </summary>
public static readonly RoutedEvent Click2Event = EventManager.RegisterRoutedEvent(
"Click2", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(Test));
/// <summary>
/// 注册路由事件,绑定方法
/// </summary>
/// <param name="handler"></param>
public void AddClick2EventHandler(RoutedEventHandler handler)
{
this.AddHandler(Click2Event, handler);
}
/// <summary>
/// 注销路由事件
/// </summary>
/// <param name="handler"></param>
public void RemoveClick2EventHandler(RoutedEventHandler handler)
{
this.RemoveHandler(Click2Event, handler);
}
public void RaiseClickEvent(string UserName)
{
//触发事件
ClickEvent.BeginInvoke(UserName,null, null);
}
/// <summary>
/// 触发路由事件
/// </summary>
/// <param name="UserName"></param>
public void RaiseClick2Event(string UserName)
{
RoutedEventArgs args = new RoutedEventArgs(Click2Event, UserName);
//触发事件
this.RaiseEvent(args);
}
}
public class TestEvent:UIElement
{
Test test = new Test();
public TestEvent()
{
test.RegisterClickEventHandler(On_Click);
this.AddHandler(Test.Click2Event, new RoutedEventHandler(On_Click2));
}
public void RaiseClick()
{
test.RaiseClick2Event("哈哈哈");
}
public void On_Click(String name)
{
Console.WriteLine(name);
}
public void On_Click2(object sender, RoutedEventArgs e)
{
}
}
为了方便XAML中进行事件绑定,我们修改下事件绑定的添加和删除,将两个方法合并为一个
public event RoutedEventHandler Click2
{
add { this.AddHandler(Click2Event, value); }
remove { this.RemoveHandler(Click2Event, value); }
}
路由事件的特点:
?从路由事件的使用方式上看,路由事侦探同依赖属性性一样,也是由WPF中的基础类型(路由事件是:EventManager;依赖属性是DependencyProperty)统一管理,从而实现路由事件共享;
?由于采用的是统一管理、统一绑定方法, 统一触发方式,所以路由事件的管理更加方便,事件传递也更加灵活;
?路由事件,之所以叫“路由”,最主要在于其事件传递的特殊性;在注册事件时,通过RoutingStrategy枚举,可以使用三种方式传递事件
?《深入浅出WPF》,以及《WPF高级编程》中都讲到当RoutedEventArgs 中Handler属性设置 true的时候,路由事件不再往下传递;其实设置Handled=true并不是终止事件的传阅,这只是为事件做一个标记而已,从业务上说明,无需再做其它处理;但是,事件还是会继续往下传递,只是处理方法是否会执行,得看我们调用UIElement.AddHandler(RoutedEvent, Delegate, Boolean)最后一个参数如何设置;
?MSDN解释如下:
?handledEventsToo Boolean
?如果为 true,则将按以下方式注册处理程序:即使路由事件在其事件数据中标记为已处理,也会调用处理程序;如果为 false,则使用默认条件注册处理程序,即当路由事件被标记为已处理时,将不调用处理程序。
原文:https://www.cnblogs.com/MonoHZ/p/14944169.html