画布上的MouseLeftButtonDown需要太多精度

时间:2009-02-24 06:14:43

标签: c# wpf canvas mouse precision

我正在响应添加到WPF画布的元素上的MouseLeftButtonDown事件。单击时一切正常(即事件处理程序正确触发),但它需要鼠标指针太精确。你必须完美地在圆圈之上才能使它发挥作用。我需要它更宽容一点;可能至少有1或2个像素宽容。画布上的元素是漂亮的大圆圈(大约在屏幕上四分之一的大小),所以圆圈本身不是太小,但每个圆圈的StrokeWidth是1,所以它是一条细线。

您可以在此处看到屏幕截图:http://twitpic.com/1f2ci/full

大多数图形应用程序对于鼠标拾取都不是那么挑剔,所以我想给用户一个熟悉的体验。

我怎样才能让它更宽容。

4 个答案:

答案 0 :(得分:4)

您可以连接到根布局对象的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个Point对象以创建虚假的容忍效果,并为所有4个点调用FindElementsInHostCoordinates或HitTest。

答案 1 :(得分:4)

您可能想尝试使用透明颜色填充圆圈,以使整个圆圈可以点击...

如果失败,您还可以在与其他圆圈相同的位置绘制辅助圆圈。使圆形前景色变为透明,并使画笔的厚度增宽几个像素,以获得圆圈周围更可接受的可点击区域。

希望这有帮助!

答案 2 :(得分:1)

我想我已经做到了(在你的帮助下让我开始)......

首先,我将移动事件处理移动到Canvas而不是每个Ellipse。从OOP的角度来看,这是好事和坏事。至少当鼠标事件处理是HolePattern负责将其设置在每个孔(椭圆是洞的视觉)上时,它被抽象掉,以便我的HolePattern的任何消费者将自动获得此功能。但是,通过将其移动到主UI代码,我现在正处理更高级别的画布鼠标事件。但这也不是坏事。我们可以讨论这部分。

关键是,我设计了一种方法,用鼠标在画布上拾取某些东西,然后读取所选椭圆属于的孔,然后我可以读取HolePattern Hole属于,我的整个UI(ListView,文本框,gridview fo坐标)都由现有的XAML绑定进行了全部更新,并且通过对现有方法的一次调用来更新Canvas以重新生成画布。

说实话,我不敢相信我已经把这一切都搞清楚了(当然,在你的帮助和其他人的帮助下)。拥有这个愿景并且看到它成为一种很酷的感觉。

查看主要代码:

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;

            }
        }
    }
}

答案 3 :(得分:1)

只需增加椭圆的行程厚度,使其可调节

因此MouseLeftButtonDown事件起作用 例: 在Ellipse标签中:

<强>椭圆  Canvas.Left =“10”Canvas.Top =“133”Height =“24”Name =“ellipse1”Width =“23”Stroke =“Red”MouseLeftButtonDown =“ellipse1_MouseLeftButtonDown”ToolTip =“Temp Close”StrokeEndLineCap =“Flat”的 StrokeThickness = “12”

private void ellipse1_MouseLeftButtonDown(object sender,MouseButtonEventArgs e)         {             应用程序curApp = Application.Current;             curApp.Shutdown();         }