第5章 路由事件(4)——附加路由事件

2016-10-08 07:58:16来源:CSDN作者:songyi160人点击

一、附加事件

在第5章路由事件(2)——冒泡路由事件文章中举的标签示例是一个非常简单的事件冒泡示例,因为所有元素都支持MouseUp事件。然而,许多控件都有各自的特殊事件。例如,按钮控件——它添加了Click事件,其他任何基类都没有定义该事件。

假设有这样一个需求,在StackPanel面板中封装了一堆按钮,并希望在一个事件处理程序中处理所有这些按钮的单击事件。粗略的方法是将每个钮的Click事件关联到同一个事件处理程序。但Click事件是冒泡路由事件,从而提供了一种更好的选择。可通过处理更高层次元素的Click事件(例如,包含按钮的StackPanel面板)来处理所有按钮的Click事件。例如以下代码,但看似浅显的代码却不能工作:

<Window x:Class="WpfApplication5_4.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:WpfApplication5_4"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <StackPanel x:Name="pnlButtons" Click="btn_Click"><!--XAML编译出错:提示StackPanel中找不到Click事件-->        <Button x:Name="btn1" Margin="5">按钮1</Button>        <Button x:Name="btn2" Margin="5">按钮2</Button>        <Button x:Name="btn3" Margin="5">按钮3</Button>        <Button x:Name="btn4" Margin="5">按钮4</Button>        <Button x:Name="btn5" Margin="5">按钮5</Button>        <Button x:Name="btn6" Margin="5">按钮6</Button>        <Button x:Name="btn7" Margin="5">按钮7</Button>    </StackPanel></Window>
出错的原因在于StackPanel面板中没有Click事件,所以XAML解析器会将其解释成错误。解决方案是以“类名.事件名”的形式使用本类中没有的事件。下面是更正后的示例XAML代码:
<Window x:Class="WpfApplication5_4.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:WpfApplication5_4"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <StackPanel x:Name="pnlButtons" Button.Click="btn_Click">        <Button x:Name="btn1" Margin="5">按钮1</Button>        <Button x:Name="btn2" Margin="5">按钮2</Button>        <Button x:Name="btn3" Margin="5">按钮3</Button>        <Button x:Name="btn4" Margin="5">按钮4</Button>        <Button x:Name="btn5" Margin="5">按钮5</Button>        <Button x:Name="btn6" Margin="5">按钮6</Button>        <Button x:Name="btn7" Margin="5">按钮7</Button>    </StackPanel></Window>
现在,事件处理程序就可以接收到StackPanel面板包含的所有按钮的单击事件了。

注意:Click事件实际是在ButtonBase类中定义的,而Button类继承了该事件。如果为ButtonBase.Click事件关联事件处理程序,那么当单击任何继承自ButtonBase的控件(包括Button类、RadioButton类以及CheckBox类)时,都会调用该事件处理程序。如果为Button.Click事件管理事件处理程序,则事件处理程序只能被Button对象使用。

CS后台代码如下:

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 WpfApplication5_4{    /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();        }        private void btn_Click(object sender, RoutedEventArgs e)        {            MessageBox.Show("Source:" + e.Source.ToString());        }    }}
效果如下:

二、代码关联附件事件

也可在代码中关联附加事件,但需要使用UIElement.AddHandler()方法,而不能使用+=运算符语法。代码如下:

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 WpfApplication5_4{    /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();            pnlButtons.AddHandler(Button.ClickEvent,new RoutedEventHandler(btn_Click));        }        private void btn_Click(object sender, RoutedEventArgs e)        {            MessageBox.Show("Source:" + e.Source.ToString());        }    }}
三、同一个事件处理程序如何区分引发事件的对象
方法一:简单地随按钮传递一段可在代码中使用的信息。例如,可为每个按钮设置Tag属性,XAML代码如下:

<Window x:Class="WpfApplication5_4.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:WpfApplication5_4"        mc:Ignorable="d"        Title="MainWindow" Height="350" Width="525">    <StackPanel x:Name="pnlButtons">        <Button x:Name="btn1" Tag="按钮1" Margin="5">按钮1</Button>        <Button x:Name="btn2" Tag="按钮2" Margin="5">按钮2</Button>        <Button x:Name="btn3" Tag="按钮3" Margin="5">按钮3</Button>        <Button x:Name="btn4" Tag="按钮4" Margin="5">按钮4</Button>        <Button x:Name="btn5" Tag="按钮5" Margin="5">按钮5</Button>        <Button x:Name="btn6" Tag="按钮6" Margin="5">按钮6</Button>        <Button x:Name="btn7" Tag="按钮7" Margin="5">按钮7</Button>    </StackPanel></Window>
CS后台代码:

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 WpfApplication5_4{    /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();        }        private void btn_Click(object sender, RoutedEventArgs e)        {            object tag = ((FrameworkElement)e.Source).Tag;            MessageBox.Show(tag.ToString());        }    }}
注意:FrameworkElement类中定义了Tag属性
显示效果如下:


方法二:在XAML中为每个按钮设置Name属性,然后在后台代码中通过Name进行区分。XAML代码与方法一相同,下面是CS后台代码:

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 WpfApplication5_4{    /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();        }        private void btn_Click(object sender, RoutedEventArgs e)        {            //object tag = ((FrameworkElement)e.Source).Tag;            //MessageBox.Show(tag.ToString());            Button bt = (Button)e.Source;            if (bt == btn1 || bt == btn2 || bt == btn3 || bt == btn4 || bt == btn5 || bt == btn6 || bt == btn7)            {                MessageBox.Show(e.Source.ToString());            }        }    }}
显示效果如下:


四、代码下载




最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台