• WPF 冒泡路由事件


        在WPF中,例如,可以构建一个包含图形的按钮,创建一个具有文本和图片混合内容的标签,或者为了实现滚动或折叠的显示效果在一个特定的容器中放置内容。甚至可以多此重复嵌套,直到达到您所希望的层次深度。

        这种可以任意嵌套的能力也带来了一个有趣的问题。例如,假设有一个标签,它包含一个StackPanel面板,该面板又包含了两块文本图像:

    <Label BorderBrush="Black" BorderThickness="1">
        <StackPanel>
            <TextBlock Margin="3">Image and text label</TextBlock>
            <Image Source="c:1.jpg" Stretch="None" />
            <TextBlock Margin="3">Courtesy of the StackPanel</TextBlock>
            </TextBlock>
        </StackPanel>
    </Label>

        正如您已经知道的,放在WPF窗口中的所有要素都在一定层次上继承自UIElement类,包括Label、StackPanel、TextBlock 和 Image 。 UIElement 定义了一些核心事件。例如,每个继承自 UIElement 的类都具有一个 MouseDown 事件和 MouseUp 事件。

        但是当单击上面这个特殊标签中的图像部分时,想一想会发生什么事情?很明显,印发Image.MouseDown 事件和 Image.MouseUp 事件是合情合理的。但是我们一般实际期望的结果并不是这样,而是无论用户单击了图像、某块文本还是标签内的空白处。不管在什么位置点击都触发同一个事件来进行处理。

        因为MouseUp事件和MouseDown事件都是冒泡路由事件,所以他们会依次向上传递事件触发,如:点击TextBlock 会依次触发:TextBlock、StackPanel、Lable、.....直到window窗体为最后一站传递点。也许这也并不是我们希望的结果,幸运的是在 WPF 中所有事件的参数类都继承自 RoutedEventArgs ,任何事件处理程序都可以使用这些属性。其中有一个 Handled 属性,则是可以终止继续往上层次冒泡的属性。该属性为True时,则终止冒泡。

        下面以一个例子来实验这种冒泡路由事件效果:

    效果:

    XAML代码:

    <Window x:Class="_1015_BubbledEvent.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid Margin="3">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="auto"/>
                <RowDefinition Height="auto"/>
            </Grid.RowDefinitions>
    
            <Label Margin="5" Grid.Row="0" HorizontalAlignment="Left" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" MouseUp="SomethingClicked">
                <StackPanel MouseUp="SomethingClicked">
                    <TextBlock Margin="3" MouseUp="SomethingClicked">Image and text label</TextBlock>
                    <Image Source="c:1.jpg" Stretch="Fill" Width="100" Height="100" MouseUp="SomethingClicked"/>
                    <TextBlock Margin="3" MouseUp="SomethingClicked">Courtesy of the StackPanel</TextBlock>
                </StackPanel>
            </Label>
            <ListBox Grid.Row="1" Margin="5" Name="lstMessage"/>
            <CheckBox Grid.Row="2" Margin="5" Name="chkHandle">Handle first event</CheckBox>
            <Button Grid.Row="3" Margin="5" Padding="3" HorizontalAlignment="Right" Name="cmdClear" Click="cmdClear_Click_1">Clear List</Button>
        </Grid>
    </Window>

    注意:代码中包含了在C:1jpg 文件,请自行随意找一个文件代替吧。

    C#代码:

            int _eventCounter = 0;
            private void SomethingClicked(object sender, MouseButtonEventArgs e)
            {
                _eventCounter++;
                string message = "#" + _eventCounter.ToString() + ":
    " +
                    " Sender: " + sender.ToString() + "
    " +
                    " Source: " + e.Source + "
    " +
                    " Original Source: " + e.OriginalSource;
                lstMessage.Items.Add(message);
                e.Handled = (bool)chkHandle.IsChecked;
            }
    
            private void cmdClear_Click_1(object sender, RoutedEventArgs e)
            {
                _eventCounter = 0;
                lstMessage.Items.Clear();
            }

    源码下载:http://files.cnblogs.com/andrew-blog/1015_BubbledEvent.rar

    使用工具:VS2012

    参考:http://www.wxzzz.com/?id=128

  • 相关阅读:
    filter函数和map函数
    生成器面试题
    装饰器激活生成器
    移动平均値
    send()方法的初识
    监听文件的输入
    迭代器抛出异常处理方法
    装饰器-wraps
    多个装饰器装饰一个函数
    WebView 安卓原生java与h5,js交互
  • 原文地址:https://www.cnblogs.com/andrew-blog/p/WPF_BubbledEvent.html
Copyright © 2020-2023  润新知