WPFのイベントは
子から親へイベントが通知されるがバブリングと
親から子へイベントが通知されるトンネリングあります。
トンネリングイベントには Preview というプレフィックスが付きます。
目的のイベントで処理を行ったら、
e.Handled = true;
をセットすることで、イベントを通知を止めることが出来ます。
イベントの通知の順番を確認するサンプルコードを書いてみました。
XAML:
<Grid PreviewMouseDown="Grid_PreviewMouseDown"
MouseDown="Grid_MouseDown">
<Button Content="Click"
PreviewMouseDown="Button_PreviewMouseDown"
MouseDown="Button_MouseDown"/>
</Grid>
コードビハイド(C#)
private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Debug.Print("Grid Preview");
}
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Debug.Print("Button Preview");
}
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
Debug.Print("Button");
}
private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
Debug.Print("Grid");
}
実行結果
Grid Preview
Button Preview
ButtonはPreviewMouseDownで
e.Handled = true;
を実行しているので、そこでイベントが終了します。
BottonをBorderに変更
<Grid PreviewMouseDown="Grid_PreviewMouseDown"
MouseDown="Grid_MouseDown">
<Border Background="LightBlue"
PreviewMouseDown="Button_PreviewMouseDown"
MouseDown="Button_MouseDown"
Width="100"
Height="50"/>
</Grid>
実行結果
Grid Preview
Button Preview
Button
Grid
Borderはそのままイベントが流れるので、
Gird→Button(Border)→Button(Border)→Grid
とイベントが折り返されます。
現実的に、全てのイベントを書くことは、余り考えられません。
Gridで受け取る、PreviewMouseDown(トンネリング・親 → 子)と
Buttonで受け取る、MouseDown(バブリング・子 → 親)
のいずれかを使う事に成ると思います。

コメント