0

ライン、パス、テキスト ボックスなどの要素がいくつかあるキャンバスがあります。MouseOverCanvas の場合、次HitTestのようなすべてのものが存在します。

bool HitTest( Point p )
{
  return VisualTreeHelper.HitTest( textBox, p ) != null;
}

これは、ラインとパスではピクセル単位で正確に機能しますが、テキスト ボックスでは期待どおりに機能しません。

たとえば、TextBox が次のように 50, 50 に配置されている場合:

Canvas.SetLeft( textBox, 50.0 );
Canvas.SetTop( textBox, 50.0 );

テキストが高さ約 20 ピクセル、幅 50 ピクセルの場合、画面上の境界矩形はおおよそ L=50 T=50 R=100 B=70 になります。

ただし、HitTest関数はその長方形では false を返し、長方形 L=0 T=0 R=50 B=20 でのみ true を返します。つまり、ヒット テストはテキスト ボックスのサイズを認識しますが、0,0 に配置されていないことを無視します。

これはなぜ起こり、どのように回避するのですか? (Line 要素と Path 要素を配置するために SetLeft/SetTop を使用しないという事実と関係があると感じています)

4

1 に答える 1

2

TextBoxがCanvasに配置されているという事実について何も知らないという理由だけで、したがって「実際の位置」については何も知りません。

呼び出すとVisualTreeHelper.HitTest(textBox, p)、ポイントpはビジュアルを基準にした座標で指定されtextBoxます。Canvasやその他の可能なコンテナのどこにTextBoxが配置されているかは関係ありません。

LineとPathの「正しい」座標(Canvasに対して)が得られるのは、Canvas.LeftまたはCanvas.Topを設定していないからです。

Canvasを基準にした座標が必要な場合は、通常、次のようにします。

bool HitTest(UIElement element, Point p)
{
    var elementPoint = new Point(
        p.X - Canvas.GetLeft(element),
        p.Y - Canvas.GetTop(element));

    return VisualTreeHelper.HitTest(element, elementPoint) != null;
}

または代わりに

bool HitTest(UIElement element, Point p)
{
    var elementPoint = canvas.TransformToDescendant(element).Transform(p);

    return VisualTreeHelper.HitTest(element, elementPoint) != null;
}
于 2012-12-13T13:10:37.663 に答える