(一)使用WPF内置路由事件
xaml:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="Simple Binding" Height="200" Width="200"> <Grid x:Name="gridRoot" Background="Lime" ButtonBase.Click="ButtonClicked"> <Grid x:Name="gridA" Margin="10" Background="Blue"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Canvas x:Name="canvasLeft" Grid.Column="0" Background="Red" Margin="10"> <Button x:Name="buttonLeft" Content="Left" Width="40" Height="100" Margin="10"/> </Canvas> <Canvas x:Name="canvasRight" Grid.Column="1" Background="Yellow" Margin="10"> <Button x:Name="buttonRight" Content="Right" Width="40" Height="100" Margin="10"/> </Canvas> </Grid> </Grid> </Window>
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; using System.Data; using MySql.Data; using MySql.Data.Entity; using MySql.Data.MySqlClient; using System.Xml; using System.Xml.Linq; using System.IO; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); //this.gridRoot.AddHandler(Button.ClickEvent, new RoutedEventHandler(this.ButtonClicked)); } private void ButtonClicked(object sender, RoutedEventArgs e) { MessageBox.Show((e.OriginalSource as FrameworkElement).Name); } } }
这里的时间从底层冒泡上去到gridRoot处侦听到该时间,才MessageBox.Show出来
(二)自定义路由事件
书上的例子有问题,不能通过
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Data; using System.Windows.Controls; namespace WpfApplication1 { class TimeButton : Button { public static readonly RoutedEvent ReportTimeEvent = EventManager.RegisterRoutedEvent ("ReportTime", RoutingStrategy.Bubble, typeof(EventHandler<ReportTimeEventArgs>), typeof(TimeButton)); public event RoutedEventHandler ReportTime { add { this.AddHandler(ReportTimeEvent, value); } remove { this.RemoveHandler(ReportTimeEvent, value); } } protected override void OnClick() { base.OnClick(); ReportTimeEventArgs args = new ReportTimeEventArgs(ReportTimeEvent, this); args.ClickTime = DateTime.Now; this.RaiseEvent(args); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; namespace WpfApplication1 { class ReportTimeEventArgs : RoutedEventArgs { public ReportTimeEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { } public DateTime ClickTime { get; set; } } }
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="Simple Binding" x:Name="window_1" Height="300" Width="300" local:TimeButton.ReportTime="ReportTimeHandler"> <Grid x:Name="grid_1" local:TimeButton.ReportTime="ReportTimeHandler"> <Grid x:Name="grid_2" local:TimeButton.ReportTime="ReportTimeHandler"> <Grid x:Name="grid_3" local:TimeButton.ReportTime="ReportTimeHandler"> <StackPanel x:Name="stackPanel_1" 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>
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; using System.Data; using MySql.Data; using MySql.Data.Entity; using MySql.Data.MySqlClient; using System.Xml; using System.Xml.Linq; using System.IO; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); //this.gridRoot.AddHandler(Button.ClickEvent, new RoutedEventHandler(this.ButtonClicked)); } private void ReportTimeHander(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); } } }