12

OnMouseイベントを子に表示させようとしていますFrameworkElement。親要素はaですPanelBackgroundプロパティはNullではありません)。

class MyFrameworkElement : FrameworkElement
{
    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        // Trying to get here!
        base.OnMouseDown(e);
    }
}

public class MyPanel : Panel
{
    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        // This is OK
        base.OnMouseDown(e);
    }
}

OnMouseが呼び出されることはなく、イベントは常に処理されず、Snoopは、ルーティングされたイベントがPanel要素までしか到達していないように見えることを通知します。

<Window 
  x:Class="WpfApplication5.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:l="clr-namespace:WpfApplication5"
  Title="Window1" Height="300" Width="300">
  <Border x:Name="myBorder" Background="Red">
    <l:MyPanel x:Name="myPanel" Background="Transparent">
      <l:MyFrameworkElement x:Name="myFE"/>
    </l:MyPanel>
  </Border>
</Window>

ドキュメントはそれが入力を処理すると言いますFrameworkElementが、なぜこのシナリオではないのですか?

4

2 に答える 2

23

OnMouseDown要素がヒット テストに応答する場合にのみ呼び出されます。ビジュアル レイヤーでのヒット テストを参照してください。デフォルトの実装では、 で描画されたグラフィックスに対してヒット テストを行いますOnRender。背景を使用して を作成するPanelと、領域全体に四角形が描画され、その四角形がヒット テストをキャッチするため機能します。透明な四角形を描画するようにオーバーライドすることで、同じ効果を得ることができます。TransparentPanelOnRender

protected override void OnRender(DrawingContext drawingContext)
{
    drawingContext.DrawRectangle(Brushes.Transparent, null, 
        new Rect(0, 0, RenderSize.Width, RenderSize.Height));
}

HitTestCoreすべてのクリックがヒットとしてカウントされるようにオーバーライドすることもできます。

protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
    return new PointHitTestResult(this, hitTestParameters.HitPoint);
}
于 2010-07-17T15:36:34.393 に答える
1

ご指摘のシナリオを再現できました。私はいくつか遊んでみましたが、の基本クラスをより具体的なものに変更するまでは、イベントが本来のように発火し始めたわけではありませんMyFrameworkElementでしFrameworkElementUserControl。これがなぜなのかは 100% わかりませんがFrameworkElement、ニーズに合った から派生したクラスの 1 つを使用することをお勧めします (Panel上記の例で行った 、または などButton)。

上記の例がこれらの結果を生成する正確な理由を知りたいです...

于 2010-07-16T22:47:21.377 に答える