Wpf事件没有冒泡

时间:2013-08-20 05:34:02

标签: c# wpf events

这是我的XAML:

<Window x:Class="WpfApplication4.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="844.025" Width="678"  MouseUp="somethingClicked">
<Grid MouseUp="somethingClicked">
    <StackPanel MouseUp="somethingClicked" Margin="0,0,10,0">
    <Button x:Name="btnClickMe" Content="Click Me!" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="101,22,0,0" MouseUp="somethingClicked"/>
        <CheckBox x:Name="chkhandle" Content="CheckBox" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="241,28,0,0" RenderTransformOrigin="-0.588,1.188"/>
        <ListBox x:Name="lstEvents" HorizontalAlignment="Left" Height="604" VerticalAlignment="Top" Width="416" Margin="29,66,0,0"/>
    </StackPanel>
</Grid>

这是C#代码:

namespace WpfApplication4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    protected int eventCounter = 0;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void somethingClicked(object sender, RoutedEventArgs e)
    {
        eventCounter++;

        String message = "#" + eventCounter.ToString() + ":\r\n" +
            " Sender: " + sender.ToString() + ":\r\n" +
            " Source: " + e.Source + ":\r\n" +
            " Original Source: " + e.OriginalSource;

        lstEvents.Items.Add(message);
        e.Handled = (bool) chkhandle.IsChecked;

        if (e.Handled)
            lstEvents.Items.Add("Completed");   

    }
}

}

我在这个例子中遇到以下问题: 1)单击按钮时不会触发MouseUp事件。 2)事件没有冒出来。单击表单上的某处显示:

Sender:WpfApplication4.MainWindow:
Source:WpfApplication4.MainWindow:
Original Source: System.Windows.Controls.Border.

如果我理解正确,当单击按钮时,首先它应该在Window级别(现在它执行),然后是Grid,然后堆栈,最后是文本标签。代码是错的还是我对这个概念的理解有缺陷?

4 个答案:

答案 0 :(得分:4)

  

The MouseUp event is not fired on clicking the button.

因为第一次火灾是Button.Click的事件,当它起作用时,它与事件MouseUp冲突。引自here

  

ButtonBase继承自UIElement,Button也可以访问为UIElement定义的所有鼠标按钮事件。因为按钮按下按钮会执行某些操作,因此会吞下冒泡事件(例如MouseLeftButtonDown和MouseDown)。您仍然可以通过为隧道事件添加处理程序来检测这些较低级别的按钮事件(例如,PreviewMouseLeftButtonDown和PreviewMouseDown)。

尝试替换Button上的Label,您将获得所需的结果:

enter image description here

答案 1 :(得分:1)

微软写了一个非常好的解释Routed Events Overview

enter image description here

{p> MouseUpPreviewMouseUp事件会发生同样的事情 在您的情况下,e.Handled = (bool) chkhandle.IsChecked;会停止事件的路由。

如果您想调试可以使用Snoop的事件,它将很好地说明哪些事件发生在哪些对象上以及谁处理它们。

答案 2 :(得分:1)

  1. 尝试处理PreviewMouseDown事件。你还可以 从XAML附上。在您的处理程序

  2. 在代码中附加事件处理程序。使用签名     AddHandler的

  3. private void Window_Loaded(object sender, RoutedEventArgs e)
    {
            Grid1.MouseUp += new MouseButtonEventHandler(Grid1_MouseUp);
    }
    private void Grid1_MouseUp(object sender, MouseButtonEventArgs e)
    {
            MessageBox.Show("Mouseup");
    }
    

答案 3 :(得分:0)

有一个覆盖可用于处理事件,即使它们被标记为已处理。它要求您通过代码添加处理程序,如下所示:

MainWindow.AddHander(UIElement.MouseUpEvent, new MouseButtonEventHandler(button1_MouseUp), true);

最后一个参数指定是否要接受已经处理的事件。如果您将该处理程序添加到主窗口,您会注意到按钮中的路由MouseUp事件确实冒泡了(但是他们的e.Handled表示它们已经被处理过了。)