5

这是我的 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.

如果我理解正确,单击按钮时,首先应该在窗口级别执行(现在执行此操作),然后是网格,然后是堆栈,最后是文本标签。是代码错误还是我对这个概念的理解有问题?

4

4 回答 4

5

The MouseUp event is not fired on clicking the button.

因为第一次触发是 的事件Button.Click,并且当它起作用时,它与事件发生冲突MouseUp从这里引用:

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

尝试替换Buttonon Label,你会得到想要的结果:

在此处输入图像描述

于 2013-08-20T06:29:13.677 回答
1

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

在此处输入图像描述

完全相同的事情会发生在你的情况下 MouseUp,事件会停止事件的路由。PreviewMouseUpe.Handled = (bool) chkhandle.IsChecked;

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

于 2013-08-20T06:17:13.813 回答
1
  1. 请尝试处理 PreviewMouseDown 事件。您仍然可以从 XAML 附加它。在你的处理程序中

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

.

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");
}
于 2013-08-20T06:22:23.567 回答
0

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

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

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

于 2013-09-08T03:15:44.397 回答