2012-05-23 34 views
0

由于事件冒泡,下面的代码应该将表单中存在的所有按钮变成绿色,但是在我的Visual Studio 2008机器上,它是只把点击的按钮变成绿色,你能帮忙解决问题吗?需要帮助理解WPF中的事件冒泡代码

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; 
    } 

} 
} 

回答

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给你。

0

由于事件处理程序btn_Click(对象发件人,MouseEventArgs e)正在发送您单击的按钮,但您无法单独使用发件人对象将文本更改为绿色。

你应该做一些类似于foreach (Button btn in myPanel.Children)的地方,你可以遍历所有按钮并更改循环中的颜色。

+0

但事件正在添加到myPanel(stackPanel),它保留所有的按钮,所以它应该适用于所有的按钮? – mohits00691

1

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