4

Canvas で多数の UserControls をヒット テストしようとしています。HitTest() でビジュアル ツリー全体を処理したくないので、FilterCallback を使用して、UserControl のみをヒット テストするようにしています。

私の問題は、UserControl がヒットしないことです。ヒットするはずですが、ヒットしません。FilterCallback を使用すると、何もヒットしなかったことを返します。HitTest をビジュアル ツリーで実行すると、UserControl がスキップされます。

ここにいくつかのコードがあります:

<Canvas x:Name="Container">
<UserControl>
   <Grid>
      <Rectangle />
   </Grid>
</UserControl>
<UserControl>
   <Grid>
      <Rectangle />
   </Grid>
</UserControl>
</Canvas>

...
VisualTreeHelper.HitTest(Container, OnFilter, OnResult, myPoint);
...

private void OnResult(DependencyObject o)
{
   //I'll get the Rectangle here, but never the userControl  
}

private void OnFilter(DependencyObject o)
{
   //I will get the UserControl here, but even when I do nothing more than continue, it will not trigger a visualHit.  But the child rectangle will.
}
4

2 に答える 2

12

これに答えるのがかなり遅いことはわかっていますが、ここに行きます: 別のアプローチは、UserControl で HitTestCore をオーバーライドし、それから期待されるデフォルトの動作を提供することです:

protected override System.Windows.Media.HitTestResult HitTestCore(System.Windows.Media.PointHitTestParameters hitTestParameters)
{
    return new PointHitTestResult(this, hitTestParameters.HitPoint);
}

(もちろん、物事を複雑にして、実際の子またはそれらのバウンディング ボックスの組み合わせのヒット テストを行うこともできますが、私にとっては、ユーザー コントロールのバウンディング ボックスで十分でした。また、ジオメトリに対してヒット テストを行う必要がある場合は、その 2 番目のオーバーロードもオーバーライドします)。

これによりHitTestFilterBehavior.ContinueSkipChildren、フィルターで使用するときに子をフィルター処理して、期待どおりに機能します。

于 2011-08-23T14:15:17.613 に答える
2

HitTestがユーザーコントロールを見つけられないという同じ問題がありました。どうやらこれは仕様によるものです(http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/005dad03-c8eb-405f-9567-50653a0e612c)。

これを回避するには、ユーザーコントロール内の要素のヒットを処理し、VisualTreeHelper.GetParentメソッドを使用して親ユーザーコントロールを見つけます。私はまだWPFに精通していないため、FrameworkElement.Parentプロパティを使用する方がよいかどうかはわかりません。

ただし、ヒットテストによってコンテンツ要素の一部を最初に見つけた後、ユーザーコントロール(または必要なタイプの視覚的な親)を見つけるための私の方法は次のとおりです。

public static T GetVisualParent<T>(this DependencyObject element) where T : DependencyObject
{
    while (element != null && !(element is T))
        element = VisualTreeHelper.GetParent(element);

    return (T)element;
}
于 2010-08-05T14:00:41.263 に答える