4

アプリに次のツリーがあります。

MainWindow (Window)
> LayoutRoot (Grid)
  > (MyCustomControl)
    > Item1 (Grid)
      > Button (Button1)

MyCustomControl は ItemsControl から派生し、その項目を StackPanel に表示します。

MyCustomControl は、マウスがクリックされたときに知る必要があるため、OnPreviewMouseDown メソッドをオーバーライドし、コントロール内でマウスが押されたときに通知を受けることを期待しています。

何が起こるか: Button1 内をクリックすると、PreviewMouseDown イベントがツリーに沿って移動し、OnPreviewMouseDown が期待どおりに実行されます。しかし、Item1 をクリックすると、PreviewMouseDown イベントは MainWindow の直後に停止し、LayoutRoot にも到達しません。

Snoopを使用して取得したルーティング イベントの詳細は次のとおりです。

Button1 のクリック:

(Window)
> (Border)
  > (AdornerDecorator)
    > (ContentPresenter)
      > LayoutRoot (Grid)
        > (MyCustomControl)
          > (Border)
            > (StackPanel)
              > Item1 (Grid)
                > Button1 (Button)
                  > Chrome (ButtonChrome)

Item1 をクリック:

(Window)
> (Border)

イベントは処理済みとして報告されることはないため、私が知る限り、トンネリングを続行する必要があります。

ここで何が欠けていますか?

4

1 に答える 1

6

カスタム コントロールがヒット テスト可能であることを確認する必要があります。次のような ControlTemplate がある場合:

<ControlTemplate>
    <ItemsPresenter />
</ControlTemplate>

その場合、カスタム コントロールはそれ自体ではヒット テスト可能ではありません。次のような ControlTemplate がある場合でも:

<ControlTemplate>
    <Border Background="{TemplateBinding Background}" ...>
        <ItemsPresenter />
    </Border>
</ControlTemplate>

次に、Background が null の場合、コントロール自体はヒット テスト可能ではありません。Background プロパティを透明に設定するだけで、ヒット テストが可能になります。

経験則では、コントロールまたはその子孫の 1 つが指定された位置 (ピクセルなど) で何かをレンダリングしない場合、たとえそれが透明であっても、マウスはそのイベントを登録しません。

于 2011-06-18T17:45:00.200 に答える