Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 改进WPF中可视层的命中测试_C#_.net_Wpf_Hittest - Fatal编程技术网

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

C# 改进WPF中可视层的命中测试,c#,.net,wpf,hittest,C#,.net,Wpf,Hittest,我在视觉层中使用下面的代码进行点击测试。当我单击在Drawingvisual中绘制的线条时,我希望获得点击。但是因为线很窄,我没有得到好的结果 我想到的一个解决方案是增加鼠标单击时的覆盖面积。通过这种方式,我将确保即使我在离线稍远的地方单击鼠标,鼠标也会碰到线 我怎样才能做到这一点?或者你还有什么建议来改善这种情况 var x = MousePos.RightDown.X; var y = MousePos.RightDown.Y; var drawing = MyCanvas.GetReba

我在视觉层中使用下面的代码进行点击测试。当我单击在
Drawing
visual中绘制的线条时,我希望获得点击。但是因为线很窄,我没有得到好的结果

我想到的一个解决方案是增加鼠标单击时的覆盖面积。通过这种方式,我将确保即使我在离线稍远的地方单击鼠标,鼠标也会碰到线

我怎样才能做到这一点?或者你还有什么建议来改善这种情况

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
)是一个派生自基类的类,甚至在基类中也有一个名为的属性,它是您要查找的可视对象(作为通用的
依赖对象
,那么您可能需要强制转换)。

使用
VisualTreeHelper.HitTest
,您可以在其中指定
HitTestParameters
,使用以
pt
为中心但大于一个点的矩形几何体,通过
GeometryHitTestParameters
VisualTreeHelper.HitTest(drawing,null,null,new GeometryHitTestParameters(…)
@AdrianoRepetti谢谢,我刚刚在探索这个选项。你能帮我写一篇文章或一个例子吗?在评论中添加,用新的矩形几何体(新的矩形(x-2,y-2,4,4))替换
。嗯……举个例子。矩形是最简单的一个,但是,特别是如果您计划将应用程序与触摸屏一起使用,圆形将更好地表示更大的点击测试区域。@AdrianoRepetti非常感谢您Adriano,我已经做到了,但我的问题是应该在哪里分配VisualTreeHelper…,正如您在我的示例中看到的,我将其分配给结果。我对这个完全陌生。代码工作得很好,非常感谢。我想只有
found=true
需要更改为
result=true
。我真的很感谢你的帮助,我在MSDN中搜索了很多,但是我没有找到一个完整的工作示例。你能给我举几个例子吗?你说得对,修好了!IMO MSDN关于该方法的示例非常好(即使很短)。首先看一下和。谢谢阿德里亚诺,这些文章帮助我更好地理解了答案。你已经帮了我很多。还有一个问题,如果需要,请告诉我,我会把它作为一个单独的问题发布。在倾向于打网球之前,我是按自己的方式做的。我的意思是,我在手动搜索行的定义,并搜索指针所在的特定行。这样我可以改变它的颜色和类似的东西。现在我正在使用HitTesting,如何才能得到我所指向的精确直线。我怎样才能得到一个引用或者类似的东西,这样我就可以对它进行修改。是的,你们可以在回调函数中进行修改。我在lambda中调用的参数
htr
(好吧,我没有太多幻想)是(它的一个派生类)。即使在基本抽象类中,也有一个属性是匹配的
DependencyObject