使用AddHandler 方法处理已经被处理的事件

所有的UIElement 实例及其子类的实例都有一个AddHandler 方法。通过该方法可以为指定的路由事件添加处理函数,并将该处理程序添加到当前元素的处理程序集合中。

AddHandler 方法有一个AddHandler(RoutedEvent, Delegate, Boolean) 的重载。

第一个参数表示指定的路由事件;

第二个参数指定事件的处理函数;

第三个参数表明是否在事件被标记为已处理的情况(e.Handled=true)下还继续处理该事件。

WPF中,事件是根据冒泡向上路由传递的,如果我们不想让事件继续传递,可以在路由的某个节点的处理函数中将e.Handled=true,表示事件已经被处理,那么后续的路由中该事件将不会被处理。但是如果使用AddHandler 方法并将第三个参数设置为true ,即使事件在之前被标记为已处理(e.Handled=true),通过AddHandler 方法添加的事件处理函数依然会执行。

 下面的例子说明AddHandler 方法第三个参数的具体作用。

<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="test"
        KeyDown="winMain_KeyDown">
    <StackPanel Orientation="Vertical" Name="spMain">
        <Label Content="Some good movies:"/>
        <StackPanel Orientation="Horizontal" Margin="10" KeyDown="spLawrence_KeyDown">
            <Label Content="Lawrence of Arabia" FontWeight="Bold"/>
            <Label Content="David Lean"/>
            <Button Content="Like" Padding="8,0"/>
            <TextBox Width="75" Margin="5,2" KeyDown="tbLawrence_KeyDown"/>
        </StackPanel>
    </StackPanel>
</Window>
上面的XAML代码中Window下面有两个StackPanel ,并且在最底层的StackPanel 中有一个TextBox 控件,我给TextBox 和包含它的底层StackPanel 以及Window注册KeyDown 事件,而作为Window根元素的StackPanel 在代码中使用AddHandler 方法注册KeyDown 事件。

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            spMain.AddHandler(UIElement.KeyDownEvent, (KeyEventHandler)spMain_KeyDown, true);
        }

        private void tbLawrence_KeyDown(object sender, KeyEventArgs e)
        {
            DumpInfo("tbLawrence_KeyDown", sender, e.Source);
        }

        private void spLawrence_KeyDown(object sender, KeyEventArgs e)
        {
            DumpInfo("spLawrence_KeyDown", sender, e.Source);
            e.Handled = true;    // The event stops here
        }

        private void spMain_KeyDown(object sender, KeyEventArgs e)
        {
            DumpInfo("spMain_KeyDown", sender, e.Source);
        }

        private void winMain_KeyDown(object sender, KeyEventArgs e)
        {
            DumpInfo("winMain_KeyDown", sender, e.Source);
        }

        private void DumpInfo(string title, object sender, object source)
        {
            System.Console.WriteLine(title + "   sender=" + sender.ToString() + "   source=" + source.ToString());
        }
    }

在上面的代码中我们在底层StackPanelKeyDown 事件处理函数spLawrence_KeyDown中将事件标记为已处理(e.Handled = true)。这样作为根元素的StackPanelWindowKeyDown 事件处理函数是不会被执行的。事实上如果没有构造函数中的

spMain.AddHandler(UIElement.KeyDownEvent, (KeyEventHandler)spMain_KeyDown, true);

这句代码的确应该是这样,但是通过这句代码作为根元素的StackPanel 注册了事件并标明及时事件被标记为处理依然执行自己的事件处理函数,程序运行后在TextBox中输入一个字符,打印的结果如下:

tbLawrence_KeyDown   sender=System.Windows.Controls.TextBox   source=System.Windows.Controls.TextBox
spLawrence_KeyDown   sender=System.Windows.Controls.StackPanel   source=System.Windows.Controls.TextBox
spMain_KeyDown   sender=System.Windows.Controls.StackPanel   source=System.Windows.Controls.TextBox

可以看到作为根元素的StackPanel 的事件处理函数执行了,但是Window 的事件处理函数没有执行。


参考文章:https://wpf.2000things.com/2012/06/20/584-handling-an-event-that-has-already-been-handled/



阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Libby1984/article/details/53580930
文章标签: AddHandler
个人分类: WPF
想对作者说点什么? 我来说一句

js访问handler中任意方法

2016年08月26日 1005B 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭