需要帮助理解WPF中的事件冒泡代码

时间:2012-05-23 15:41:34

标签: c# wpf events event-bubbling

由于事件冒泡,以下代码应该将表单中存在的所有按钮变为绿色,但是在我的Visual Studio 2008上的计算机上,它只将点击的按钮变为绿色,你能帮忙找出问题吗?

XAML代码(window1.xaml):

<Window x:Class="EventRouting.Window1" Title="Event Routing" Height="300" Width="300"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Border Margin="15" BorderBrush="Blue" BorderThickness="5" Padding="15"
            CornerRadius="12" x:Name="myBorder" Background="Transparent">
<StackPanel x:Name="myPanel" Background="Transparent">
  <Ellipse x:Name="myEllipse" Margin="3" Fill="Green" Height="40" />
  <Rectangle x:Name="myRectangle" Margin="3" Fill="Cyan" Height="40" RadiusX="10" RadiusY="10" />
</StackPanel>

CS代码(window1.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;
using System.Diagnostics;

namespace EventRouting
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            this.MouseEnter += MouseEnterHandler;
        myBorder.MouseEnter += MouseEnterHandler;
        myPanel.MouseEnter += MouseEnterHandler;
        myEllipse.MouseEnter += MouseEnterHandler;
        myRectangle.MouseEnter += MouseEnterHandler;

        this.MouseDown += MouseDownHandler;
        myBorder.MouseDown += MouseDownHandler;
        myPanel.MouseDown += MouseDownHandler;
        myEllipse.MouseDown += MouseDownHandler;
        myRectangle.MouseDown += MouseDownHandler;

        for (int i = 1; i <= 5; ++i)
        {
            Button btn = new Button();
            btn.Content = "Button " + i;
            myPanel.Children.Add(btn);

            //btn.Click += new RoutedEventHandler(btn_Click);
        }

        myPanel.AddHandler(Button.ClickEvent, new RoutedEventHandler(btn_Click));
    }

    void btn_Click(object sender, RoutedEventArgs e)
    {
        Button btn = (Button) e.Source;
        btn.Background = Brushes.Green;
    }

    void MouseEnterHandler(object sender, MouseEventArgs e)
    {
        Debug.WriteLine("MouseEnter: " + sender);
    }
    void MouseDownHandler(object sender, MouseButtonEventArgs e)
    {
        Debug.WriteLine("MouseDown: " + sender);
        e.Handled = true;
    }

}
}

3 个答案:

答案 0 :(得分:2)

路由事件会在可视树中冒泡,直到它们被处理完毕。使用您的XAML,尝试使用此代码。

    public MainWindow()
    {
        InitializeComponent();
        myEllipse.AddHandler(UIElement.MouseDownEvent, new RoutedEventHandler(OnMouseDown));
        myPanel.AddHandler(UIElement.MouseDownEvent, new RoutedEventHandler(OnMouseDown));
        myBorder.AddHandler(UIElement.MouseDownEvent, new RoutedEventHandler(OnMouseDown));
    }

    void OnMouseDown(object sender, RoutedEventArgs e)
    {
        UIElement uiElement = sender as UIElement;
        Debug.WriteLine(uiElement.GetType().ToString());
        e.Handled = true;
    }

如果您注释掉e.Handled = true行,该事件将冒泡到父元素。这对你来说是一个很好的link

答案 1 :(得分:1)

如果我理解你想要的是从根(面板)到每个孩子(按钮)的隧道事件。路由隧道事件不会这样做,它们只从根到源元素,而不是兄弟。请参阅Overview of routed events in WPF,并举例说明。

答案 2 :(得分:0)

因为事件处理程序btn_Click(对象发送者,MouseEventArgs e)正在发送您单击的按钮,所以您不能单独使用sender对象将文本更改为绿色。

您应该执行foreach (Button btn in myPanel.Children)之类的操作,循环浏览所有按钮并更改循环中的颜色。

相关问题