改善视觉层在WPF命中测试 [英] Improve hit testing in the visual layer in WPF
问题描述
我用下面的$ C $下点击测试
在视觉层。我想获得的点击,当我点击那个被画在绘图
视觉线。但由于线很窄,我没有收到很好的效果。
一个解决方案,在我脑海中不断增加的区域鼠标盖点击时。这样,我会确保鼠标点击的线条,即使我点击一点点进一步从线。
我怎样才能做到这一点?或者,你还有什么建议来改善这种情况呢?
变种X = MousePos.RightDown.X;
变种Y = MousePos.RightDown.Y;
VAR绘图= MyCanvas.GetRebarsVisual();
VAR PT =新的点(X,Y);
VAR的结果= VisualTreeHelper.HitTest(图纸,PT);
如果(结果!= NULL)
{
的MessageBox.show(你点击就行了!);
}
使用 VisualTreeHelper.HitTest()
重载函数,你可以指定一个 HitTestParameters
:用一个矩形几何中心 PT
(但大于1点)通过了 GeometryHitTestParameters
:
VAR hitRect =新的矩形(X - 2,Y - 2,4,4);
VisualTreeHelper.HitTest(拉丝,NULL,NULL,
新GeometryHitTestParameters(新RectangleGeometry(hitRect)));
请注意,我们使用的是在这个例子中矩形几何形状,但一个更接近(特别是对触摸屏)是一个圆( EllipseGeometry
)。
现在你知道叫什么,但你需要一个结果,超载没有一个返回值,而不是它使用一个回调函数,你可以积累多次点击(根据更复杂的规则选择一个)。在我们的例子中,我们并不需要它,所以我们仅仅停留在第一击:
布尔结果= FALSE;
变种hitRect =新的Rect(X - 2,Y - 2,4,4);
VisualTreeHelper.HitTest(绘图,空,
HTR => {结果= TRUE;返回HitTestResultBehavior.Stop; },
新GeometryHitTestParameters(新RectangleGeometry(hitRect)));
请注意,您甚至可以直接执行code:
HTR => {
的MessageBox.show(你点击就行了!);
返回HitTestResultBehavior.Stop;
},
如果你经常使用它,你可以写一个更通用的方法是(例如与矩形大小可选参数)。
如果你只是不想知道是否有一个命中与否(但你也想知道哪个对象),那么你可以使用第二个回调函数(<$ C C $> HitTestResultCallback ),它的参数(一个名为 HTR
在我的previous例子)是的 HitTestResult
甚至在基类中有一个名为属性<一个href="http://msdn.microsoft.com/en-us/library/system.windows.media.hittestresult.visualhit(v=vs.110).aspx"相对=nofollow> VisualHit
这是视觉对象(如一个普通的的DependencyObject
那么你可能需要铸造),你要寻找的。 P>
I'm using the code below for Hit Testing
in the visual layer. I want to get hits when I click on the lines that are drawn in Drawing
visual. But since lines are narrow, I'm not getting good results.
One solution that comes to my mind is increasing the area mouse covers when clicked. This way I'll make sure that the mouse hits the lines even if I click a little bit further from the line.
How can I achieve this? Or what else do you suggest to improve this situation?
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!");
}
Using VisualTreeHelper.HitTest()
overloaded function where you can specify a HitTestParameters
: use a rectangle geometry centered on pt
(but bigger than one point) passed with GeometryHitTestParameters
:
var hitRect = new Rect(x - 2, y - 2, 4, 4);
VisualTreeHelper.HitTest(drawing, null, null,
new GeometryHitTestParameters(new RectangleGeometry(hitRect)));
Note that we're using a rectangular geometry in this example but a better approximation (especially for touch screens) is a circle (EllipseGeometry
).
Now you know what to call but you need a result, that overload has not a return value instead it uses a callback function where you can accumulate multiple hits (to pick one according to more complex rules). In our example we don't need it so we just stop at first hit:
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)));
Note that you may even directly execute code:
htr => {
MessageBox.Show("You clicked on the line!");
return HitTestResultBehavior.Stop;
},
If you use it often you may write a more generic method for that (for example with an optional parameter for rectangle size).
If you just don't want to know if there is a hit or not (but you also want to know which object) then you can use second callback function (HitTestResultCallback
), its parameter (the one called htr
in my previous example) is a class derived from HitTestResult
and even in base class there is a property named VisualHit
which is the visual object (as a generic DependencyObject
then you may need casting) you're looking for.
这篇关于改善视觉层在WPF命中测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!