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 处。

为什么会发生这种情况,以及如何解决?(我感觉这与我不使用 SetLeft/SetTop 定位 Line 和 Path 元素有关)

4

1 回答 1

2

仅仅是因为 TextBox 对它位于 Canvas 中的事实一无所知,因此对“实际位置”一无所知。

当您调用时VisualTreeHelper.HitTest(textBox, p),Pointp以相对于textBox视觉的坐标给出。与 TextBox 在 Canvas 或任何其他可能的容器中的位置无关。

您获得 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 回答