一、创建RoutedEventArgs类的派生类,为其添加ClickTime属性
//承载时间信息的事件参数
class ReportTimeEventArgs : RoutedEventArgs
{
public ReportTimeEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { }
public DateTime ClickTime { get; set; }
}
二、创建button类的派生类并按照前面的步骤为其添加路由事件
创建自定义路由器的三步骤:
1、声明并注册路由事件
2、为路由事件添加CLR事件包装
3、创建可以激发路由事件的方法
class TimeButton : Button
{
//声明和注册路由事件
public static readonly RoutedEvent ReportTimeEvent = EventManager.RegisterRoutedEvent
("ReportTime",RoutingStrategy.Bubble,typeof(EventHandler<ReportTimeEventArgs>),typeof(TimeButton));
//CLR事件包装器
public event RoutedEventHandler ReportTime
{
add { this.AddHandler(ReportTimeEvent, value); }
remove { this.RemoveHandler(ReportTimeEvent, value); }
}
//激发路由器事件,借用click事件的激发方法
protected override void OnClick()
{
base.OnClick();
ReportTimeEventArgs args = new ReportTimeEventArgs(ReportTimeEvent, this);
args.ClickTime = DateTime.Now;
this.RaiseEvent(args);
}
}
三、界面xmal
<Window x:Class="WpfApplicationTimeButton.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplicationTimeButton" Title="Rounted Event"
mc:Ignorable="d"
x:Name="window_1" Height="350" Width="525"
//ReportTimeHandler是转定义生成的,但是需要修改
local:TimeButton.ReportTime="ReportTimeHandler">
<Grid x:Name="gridA" local:TimeButton.ReportTime="ReportTimeHandler">
<Grid x:Name="gridB" local:TimeButton.ReportTime="ReportTimeHandler">
<Grid x:Name="gridC" local:TimeButton.ReportTime="ReportTimeHandler">
<StackPanel x:Name="stackA" 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>
</Window>
四、编写ReportTimeHandler
//注意第二个参数类型 转定义过来需要改变
private void ReportTimeHandler(object sender, ReportTimeEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
string timeStr = e.ClickTime.ToLongTimeString();
string content = string.Format("{0} 到达 {1}", timeStr, element.Name);
this.listBox.Items.Add(content);
}
五、运行效果
六、整体代码
MainWindow.xaml
<Window x:Class="WpfApplicationTimeButton.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplicationTimeButton" Title="Rounted Event"
mc:Ignorable="d"
x:Name="window_1" Height="350" Width="525"
local:TimeButton.ReportTime="ReportTimeHandler">
<Grid x:Name="gridA" local:TimeButton.ReportTime="ReportTimeHandler">
<Grid x:Name="gridB" local:TimeButton.ReportTime="ReportTimeHandler">
<Grid x:Name="gridC" local:TimeButton.ReportTime="ReportTimeHandler">
<StackPanel x:Name="stackA" 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>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 WpfApplicationTimeButton
{
//用于承载时间消息的事件参数
class ReportTimeEventArgs : RoutedEventArgs
{
public ReportTimeEventArgs(RoutedEvent routedEvent, object source)
: base(routedEvent, source) { }
public DateTime ClickTime { get; set; }
}
public class TimeButton : Button
{
//声明和注册路由事件
public static readonly RoutedEvent ReportTimeEvent = EventManager.RegisterRoutedEvent
("ReportTime", RoutingStrategy.Bubble, typeof(EventHandler<ReportTimeEventArgs>), typeof(TimeButton));
//CLR事件包装器
public event RoutedEventHandler ReportTime
{
add { this.AddHandler(ReportTimeEvent, value); }
remove { this.RemoveHandler(ReportTimeEvent, value); }
}
//激发路由器事件,借用click事件的激发方法
protected override void OnClick()
{
base.OnClick();
ReportTimeEventArgs args = new ReportTimeEventArgs(ReportTimeEvent, this);
args.ClickTime = DateTime.Now;
this.RaiseEvent(args);
}
}
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ReportTimeHandler(object sender, ReportTimeEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
string timeStr = e.ClickTime.ToLongTimeString();
string content = string.Format("{0} 到达 {1}", timeStr, element.Name);
this.listBox.Items.Add(content);
}
}
}
七、遇到问题
错误 CS1061 “RoutedEventArgs”未包含“ClickTime”的定义,并且找不到可接受第一个“RoutedEventArgs”类型参数的扩展方法“ClickTime”(是否缺少 using 指令或程序集引用?) WpfApplicationTimeButton
ReportTimeHandler转定义过来需要改变其第二个传入参数的类型