为什么会有两种情况,刚接触的可能有这样的疑问。
ValueText.PreviewMouseWheel += mouseAngleChange;
UpButton.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(UpButton_MouseDown), true);
为什么用下边的写法就出现错误:error CS0176: 无法使用实例引用访问成员"System.Windows.UIElement.MouseLeftButtonDownEvent。
UpButton.MouseLeftButtonDownEvent += UpButton_MouseDown;
这里需要看定义,可以看出他们一个是静态成员,一个不是静态成员,所以MouseLeftButtonDownEvent只能由类Button直接调用,不能由实例化的UpButton调用。
public event MouseWheelEventHandler PreviewMouseWheel;
public static readonly RoutedEvent MouseLeftButtonDownEvent;
///
WPF 路由事件(RoutedEventArgs 事件消息、 RoutedEvent 路由事件、RoutedEventHandler路由事件处理程序、RaiseEvent引发路由事件)
https://blog.youkuaiyun.com/litao2/article/details/54947009这篇文章讲的非常好。
自定义路由事件:
//定义路由事件
public static readonly RoutedEvent AngleChangeEvent =
EventManager.RegisterRoutedEvent("AngleChange", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ServoView));
public event RoutedEventHandler AngleChange
{
add
{
this.AddHandler(AngleChangeEvent, value);
}
remove
{
this.RemoveHandler(AngleChangeEvent, value);
}
}
public void OnAngleChange(double value)//角度变化,将该信息发送出去,MainWindow的servosView侦听了该事件
{
this.curAngle = value;
servoAngleSlider.Value = value;
RoutedEventArgs arg = new RoutedEventArgs(AngleChangeEvent, this);
this.RaiseEvent(arg);
}
这里就可以通过该方法增加事件的实现。
servosViewList[i].AddHandler(ServoView.AngleChangeEvent, new RoutedEventHandler(this.angleChangeHandler));
这里是一个例子。转的https://blog.youkuaiyun.com/litao2/article/details/54947009
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace WpfApplication
{
/// <summary>
/// Window6.xaml 的交互逻辑
/// </summary>
public partial class Window6 : Window
{
public Window6()
{
InitializeComponent();
//事件、委托指向方法
mybutton.Open+=new RoutedEventHandler(mybutton_Open);
}
public void mybutton_Open(object sender, RoutedEventArgs e)
{
MessageBox.Show("打开");
}
}
class MyButton : Button
{
//第一步:声明并注册【路由事件】
//EventManager.RegisterRoutedEvent(CLR事件包装器名称,路由事件冒泡策略,
//事件处理程序的类型,路由事件的所有者类类型)
public static readonly RoutedEvent OpenEvent = EventManager.RegisterRoutedEvent
("Open",RoutingStrategy.Bubble,typeof(RoutedEventHandler),typeof(MyButton));
//第二步:为路由事件添加CLR事件包装器
public event RoutedEventHandler Open
{
add { this.AddHandler(OpenEvent, value); }
remove { this.RemoveHandler(OpenEvent, value); }
}
//第三步:激发路由事件
protected override void OnClick()
{
base.OnClick();
//创建事件携带信息(RoutedEventArgs类实例),并和路由事件关联
RoutedEventArgs args = new RoutedEventArgs(OpenEvent,this);
//调用元素的RaiseEvent方法(继承自UIElement类),将事件发出去
this.RaiseEvent(args);
}
}
}
<Window x:Class="WpfApplication.Window6"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
Title="Window6" Height="300" Width="300">
<Grid>
<local:MyButton Content="测试" x:Name="mybutton"/>
</Grid>
</Window>
这里对这个例子进行修改
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace test2
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//事件、委托指向方法
mybutton.Open += new RoutedEventHandler(mybutton_Open);
mybutton.AddHandler(MyButton.OpenEvent,new RoutedEventHandler(this.mybutton_Open1));
mybutton.AddHandler(MyButton.OpenEvent, new RoutedEventHandler(this.mybutton_Open1));
mybutton.AddHandler(MyButton.OpenEvent, new RoutedEventHandler(this.mybutton_Open1));
}
public void mybutton_Open(object sender, RoutedEventArgs e)
{
MessageBox.Show("打开");
}
public void mybutton_Open1(object sender, RoutedEventArgs e)
{
MessageBox.Show("关闭");
}
}
class MyButton : Button
{
//第一步:声明并注册【路由事件】
//EventManager.RegisterRoutedEvent(CLR事件包装器名称,路由事件冒泡策略,
//事件处理程序的类型,路由事件的所有者类类型)
public static readonly RoutedEvent OpenEvent = EventManager.RegisterRoutedEvent
("Open",RoutingStrategy.Bubble,typeof(RoutedEventHandler),typeof(MyButton));
//第二步:为路由事件添加CLR事件包装器
public event RoutedEventHandler Open
{
add { this.AddHandler(OpenEvent, value); }
remove { this.RemoveHandler(OpenEvent, value); }
}
//第三步:激发路由事件
protected override void OnClick()
{
base.OnClick();
//创建事件携带信息(RoutedEventArgs类实例),并和路由事件关联
RoutedEventArgs args = new RoutedEventArgs(OpenEvent,this);
//调用元素的RaiseEvent方法(继承自UIElement类),将事件发出去
this.RaiseEvent(args);
}
}
}
<Window x:Class="test2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:test2"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:MyButton Content="测试" x:Name="mybutton"/>
</Grid>
</Window>
可以知道这里用
mybutton.Open += new RoutedEventHandler(mybutton_Open);
mybutton.AddHandler(MyButton.OpenEvent,new RoutedEventHandler(this.mybutton_Open1));
这两种方法都可以实现路由事件的添加,正如文章最开始讨论的问题那样,只不过是两种不同的方式。
mybutton.AddHandler(MyButton.OpenEvent,new RoutedEventHandler(this.mybutton_Open1));
mybutton.AddHandler(MyButton.OpenEvent, new RoutedEventHandler(this.mybutton_Open1));
mybutton.AddHandler(MyButton.OpenEvent, new RoutedEventHandler(this.mybutton_Open1));
这里连续写三次,则程序会连续的执行三次该路由事件。
具体程序已经贴出,如果有问题的,可以参考这里https://download.youkuaiyun.com/download/yanxiaoyunsana/10975277。