0

由于事件冒泡,以下代码应该在其中一个按钮单击时将表单中存在的所有按钮变为绿色,但在我的 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;
    }

}
}
4

3 回答 3

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 行,该事件将冒泡到父元素。这是一个很好的链接

于 2012-05-23T16:19:05.310 回答
1

如果我了解您想要的是从根(面板)到每个孩子(按钮)的隧道事件。路由隧道事件不会这样做,它们只会从根元素遍历到源元素,而不是兄弟元素。请参阅WPF 中的路由事件概述,其中有一个很好的说明。

于 2012-05-23T16:20:14.220 回答
0

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

你应该做一些事情,比如foreach (Button btn in myPanel.Children)循环遍历所有按钮并更改循环中的颜色。

于 2012-05-23T16:07:14.233 回答