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
。