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>
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
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イベントなどのように、新しい概念が導入されているんですね。