我正在响应添加到WPF画布的元素上的MouseLeftButtonDown事件。单击时一切正常(即eventhandler正确触发),但它对鼠标指针的精确度要求太高。你必须完美地站在圈子的顶端才能让它工作。我需要更多的宽容度;也许至少有1到2个像素的宽容度。画布上的元素是漂亮的大圆圈(大约是屏幕上的四分之一大小),所以圆圈本身并不太小,但每个圆圈的StrokeWidth是1,所以它是一条细线。
你可以在这里看到一个截图:http://twitpic.com/1f2ci/full
大多数图形应用程序在鼠标选择上不会这么挑剔,所以我想给用户一种熟悉的体验。
我怎么才能让它变得更宽宏大量。
发布于 2009-02-24 07:11:08
您可以改为挂钩到根布局对象的MouseLeftButtonDown事件,并通过执行以下操作来检查哪些元素在单击范围内:
List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(Point, yourLayoutRootElement) as List<UIElement>;
http://msdn.microsoft.com/en-us/library/cc838402(VS.95).aspx
对于Point参数,可以使用MouseEventArgs参数e,并按如下方式调用其GetPosition方法:
Point p = e.GetPosition(null)
我不记得是否使用HitTest而不是FindElementsInHostCoordinates。两个都试一下。
http://msdn.microsoft.com/en-us/library/ms608752.aspx
可以从鼠标位置创建4个点对象以创建虚假容差效果,并为所有4个点调用FindElementsInHostCoordinates或HitTest。
发布于 2009-02-24 15:12:46
你可能想尝试用透明的颜色填充圆圈,使整个圆圈可点击…
如果失败,您还可以在与其他圆相同的位置绘制辅助圆。使圆形前景色透明,并将画笔的厚度加宽几个像素,以便在圆形周围有一个更容易接受的可点击区域。
希望这能有所帮助!
发布于 2009-02-24 16:38:39
我想我已经做到了(在你的帮助下开始了)……
首先,我将移动事件处理移动到画布,而不是每个椭圆。从OOP的角度来看,这是好的,也是坏的。至少当鼠标事件处理是HolePattern在每个洞上设置鼠标事件的责任时(椭圆是洞的视觉),它被抽象掉了,这样我的HolePattern的任何使用者都会自动获得这个功能。但是,通过将其移动到主UI代码,我现在可以在更高的级别上处理我的画布鼠标事件。但这也不全是坏事。我们可以讨论这部分几天。
重点是,我设计了一种方法,当用鼠标在画布上拾取某些东西时,然后读取所选椭圆所属的孔,然后我可以读取该孔所属的HolePattern,并且我的整个UI (ListView、文本框、网格视图和坐标)都由现有的XAML绑定更新,并且画布通过调用现有方法重新生成画布来更新。
老实说,我不敢相信我已经弄明白了这一切(当然是在你的帮助和其他人的帮助下)。这是一种如此酷的感觉,有这样的愿景,并看到它成为现实。
在这里查看主要代码:
void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
int ClickMargin = 2;
Point ClickedPoint = e.GetPosition(canvas1);
Point p1 = new Point(ClickedPoint.X - ClickMargin, ClickedPoint.Y - ClickMargin);
Point p2 = new Point(ClickedPoint.X - ClickMargin, ClickedPoint.Y + ClickMargin);
Point p3 = new Point(ClickedPoint.X + ClickMargin, ClickedPoint.Y + ClickMargin);
Point p4 = new Point(ClickedPoint.X + ClickMargin, ClickedPoint.Y - ClickMargin);
var PointPickList = new Collection<Point>();
PointPickList.Add(ClickedPoint);
PointPickList.Add(p1);
PointPickList.Add(p2);
PointPickList.Add(p3);
PointPickList.Add(p4);
foreach (Point p in PointPickList)
{
HitTestResult SelectedCanvasItem = System.Windows.Media.VisualTreeHelper.HitTest(canvas1, p);
if (SelectedCanvasItem.VisualHit.GetType() == typeof(Ellipse))
{
var SelectedEllipseTag = SelectedCanvasItem.VisualHit.GetValue(Ellipse.TagProperty);
if (SelectedEllipseTag!=null && SelectedEllipseTag.GetType().BaseType == typeof(Hole))
{
Hole SelectedHole = (Hole)SelectedEllipseTag;
SetActivePattern(SelectedHole.ParentPattern);
SelectedHole.ParentPattern.CurrentHole = SelectedHole;
}
}
}
}
https://stackoverflow.com/questions/580641
复制相似问题