我在可视层中将以下代码用于Hit Testing
。当我单击以Drawing
视觉方式绘制的线条时,我希望获得点击。但是由于线条很窄,所以效果不好。
我想到的一种解决方案是增加单击鼠标时的覆盖面积。通过这种方式,即使我从该行稍稍单击一点,也可以确保鼠标点击了这些行。
我该如何实现?或者您还建议采取什么措施来改善这种情况?
var x = MousePos.RightDown.X;
var y = MousePos.RightDown.Y;
var drawing = MyCanvas.GetRebarsVisual();
var pt = new Point(x,y);
var result = VisualTreeHelper.HitTest(drawing, pt);
if (result != null)
{
MessageBox.Show("You clicked on the line!");
}
最佳答案
使用VisualTreeHelper.HitTest()
重载函数,您可以在其中指定HitTestParameters
:使用以pt
(但大于一个点)为中心的矩形几何体,该矩形由GeometryHitTestParameters
传递:
var hitRect = new Rect(x - 2, y - 2, 4, 4);
VisualTreeHelper.HitTest(drawing, null, null,
new GeometryHitTestParameters(new RectangleGeometry(hitRect)));
请注意,在此示例中我们使用的是矩形几何形状,但是更好的近似值(尤其是对于触摸屏)是圆形(
EllipseGeometry
)。现在您知道要调用什么,但需要一个结果,该重载没有返回值,而是使用了一个回调函数,您可以在该函数中累积多个匹配(根据更复杂的规则选择一个)。在我们的示例中,我们不需要它,因此我们仅在第一击时停止:
bool result = false;
var hitRect = new Rect(x - 2, y - 2, 4, 4);
VisualTreeHelper.HitTest(drawing, null,
htr => { result = true; return HitTestResultBehavior.Stop; },
new GeometryHitTestParameters(new RectangleGeometry(hitRect)));
请注意,您甚至可以直接执行代码:
htr => {
MessageBox.Show("You clicked on the line!");
return HitTestResultBehavior.Stop;
},
如果经常使用它,则可以为此编写一个更通用的方法(例如,使用用于矩形大小的可选参数)。
如果您只是不想知道是否有命中(但您也想知道哪个对象),则可以使用第二个回调函数(
HitTestResultCallback
),其参数(在我的函数中称为htr
前面的示例)是一个从HitTestResult
派生的类,即使在基类中,也有一个名为VisualHit
的属性,它是您正在寻找的可视对象(作为通用DependencyObject
,则可能需要强制转换)。