改进WPF中可视层的命中测试

时间:2014-09-09 21:35:58

标签: c# .net wpf hittest

我在视觉图层中使用以下代码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!");
}

1 个答案:

答案 0 :(得分:2)

使用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),它的参数(在我之前的例子中,一个名为DependencyObject的类是一个派生自HitTestResult的类,甚至在基类中也有一个名为VisualHit的属性,它是一个可视对象(作为通用{{1}}那么你可能需要施展)你正在寻找。