Routedイベント

WPFでのイベントはRoutedイベントと呼ばれ、Direct、Tunneling、Bubblingの3種類が存在します。
biacさんが下記のページで書かれていますので、こちらを読むと概要が分かるかと思います。

http://akari.kabe.co.jp/MagSite/Content.modf?id=20060822163318

ルーティングは大きく分けて 2種類、 Direct と Tunneling/Bubbling のイベントに分かれます。 ターゲット要素で直接発生するイベントが Direct です。 もう一方は、 上位 ( 一番外側のコンテナ) からターゲット要素へ向かって Tunneling イベント ( Preview イベント) が降りていき、 ターゲットに到達すると、 こんどはそこから上位に向かって Bubbling イベントが伝達されていきます。

MSDNライブラリではこの辺に書かれています。

http://windowssdk.msdn.microsoft.com/en-us/library/ms742806.aspx



Routed EventのTunnelingとBubblingを図で示すとこのような感じになります。

Grid1が一番外側のコンテナで、ターゲットはButton1です。では、実際にこの図と同じ構成のアプリケーションを作成して、イベントの発生を確認してみたいと思います。


XAML

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="RoutedEvent" Height="300" Width="300" FontSize="18">
 
    <Grid Button.PreviewMouseDown="tunneling1" Button.Click="bubbling3">
 
      <Grid.RowDefinitions>
        <RowDefinition Height="0.7*"/>
        <RowDefinition Height="0.3*"/>
      </Grid.RowDefinitions>
 
      <ListBox Grid.Row="0" Name="ListBox1"/>
 
      <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center"
                  Margin="10" Background="LightBlue" Name="StackPanel1"
                  Button.PreviewMouseDown="tunneling2" Button.Click="bubbling2">
        <Button Margin="10" Name="Button1"
                PreviewMouseDown="tunneling3" Click="bubbling1">はい</Button>
        <Button Margin="10" Name="Button2">いいえ</Button>
        <Button Margin="10" Name="Button3">キャンセル</Button>
      </StackPanel>
 
    </Grid>
 
</Window>


Visual Basic
Partial Public Class Window1
    Inherits System.Windows.Window
 
    Public Sub New()
        InitializeComponent()
    End Sub
 
    ' Grid
    Private Sub tunneling1(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        ListBox1.Items.Add("Grid tunneling1:" + CType(e.Source, FrameworkElement).Name.ToString)
    End Sub
 
    Private Sub bubbling3(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ListBox1.Items.Add("Grid bubbling3:" + CType(e.Source, FrameworkElement).Name.ToString)
    End Sub
 
    ' StackPanel
    Private Sub tunneling2(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        ListBox1.Items.Add("StackPanel tunneling2:" + CType(e.Source, FrameworkElement).Name.ToString)
    End Sub
 
    Private Sub bubbling2(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ListBox1.Items.Add("StackPanel bubbling2:" + CType(e.Source, FrameworkElement).Name.ToString)
    End Sub
 
    ' Button
    Private Sub tunneling3(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
        ListBox1.Items.Add("Button tunneling3:" + CType(e.Source, FrameworkElement).Name.ToString)
    End Sub
 
    Private Sub bubbling1(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ListBox1.Items.Add("Button bubbling1:" + CType(e.Source, FrameworkElement).Name.ToString)
    End Sub
 
End Class


これを実行しますと、こんな感じになります。

ターゲットであるButton1に向かって一番外側のGrid1からTunnelingイベントが降りていき、今度は逆にターゲットから一番外側のコンテナへ向かってBubblingイベントが上がっていくのが分かるかと思います。
XAMLによるレイアウトでは各エレメントが親子の関係を持つことが基本となってきますので、AttachedプロパティやこのRoutedイベントなどのように、新しい概念が導入されているんですね。