如果光标被锁定,则检测鼠标移动

时间:2017-02-28 19:36:05

标签: c# winforms cad

我正在开发Cad应用程序并希望实现快照 - 当用户将鼠标移动到某个对象附近时,我将Cursor.Position设置为该对象的中心点。如果用户在任何方向上移动鼠标说7个像素,则Cursor被释放。我的方法是 - 我存储snaped Cursor位置然后在MouseMoveEvent下我计算从存储位置到当前位置的距离。如果此位置小于定义的阈值,则将当前光标位置设置回存储值。每次调用MouseMoveEvent时,两个光标位置之间的微小差异都会添加到先前已计算的差异中,所以迟早会达到我的阈值并且Cursor跳出snaped位置。代码示例:

   var x = Cursor.Position.X - storedPosition.X;
   pixelsX += x;

   int threshold = 7;
   if (pixelsX > threshold)
   {
          Cursor.Position = new System.Drawing.Point(storedPosition.X + 10, storedPosition.Y);
          snapReleased = true;
   }

这个问题是每个MouseMoveEvent鼠标移动的数量非常少,如果没有达到阈值,它会被设置回存储位置,这会使Cursor闪烁(这很烦人)所以我的问题是 - 有没有办法如果光标锁定在一个位置,检测鼠标移动?

2 个答案:

答案 0 :(得分:3)

我不会" snap"鼠标指针。你知道鼠标卡住的感觉吗?根据您的年龄,您可能会记得滚轮老鼠,里面有橡皮球的老鼠。太可怕了。

相反,我认为您要选择或正在移动的对象应该快速响应。例如,当您要选择一个对象时,当鼠标指针比阈值更接近时,对象将突出显示。用户可以单击鼠标并抓取对象。

当移动一个物体时,物体可以在比阈值更接近另一个物体,引导线等时捕捉到位。

答案 1 :(得分:1)

以下是一个自定义面板控件,用于演示捕捉到网格(snapPoints)的所有者绘制光标。鼠标进入/离开时隐藏/显示系统光标。对齐点距离由常量snapLimit控制。

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;

namespace WindowsFormsApplication1
    {

    public class DrawingSurface : Panel
        {
        private const double snapLimit = 7.0D;
        private List<Point> snapPoints = new List<Point>();
        private Point cursorPos;
        private Point lastDrawnPos;
        private bool drawCursor;

        public DrawingSurface() : base()
            {
            this.BorderStyle = BorderStyle.Fixed3D;
            this.BackColor = Color.AliceBlue;
            this.DoubleBuffered = true;
            this.Cursor = Cursors.Cross;
            }

        protected override void OnMouseEnter(EventArgs e)
            {
            base.OnMouseEnter(e);
            System.Windows.Forms.Cursor.Hide();
            }

        protected override void OnMouseLeave(EventArgs e)
            {
            base.OnMouseLeave(e);
            System.Windows.Forms.Cursor.Show();
            this.drawCursor = false;
            this.Invalidate();
            }

        protected override void OnPaint(PaintEventArgs e)
            {
            base.OnPaint(e);
            foreach (Point dot in this.snapPoints)
                {
                e.Graphics.FillEllipse(Brushes.Red, dot.X - 1, dot.Y - 1, 2, 2);
                }
            if (drawCursor)
                {
                Cursor cur = System.Windows.Forms.Cursor.Current;
                Point pt = this.cursorPos;
                pt.Offset(-cur.HotSpot.X, -cur.HotSpot.Y);
                Rectangle target = new Rectangle(pt, cur.Size);
                cur.Draw(e.Graphics, target);
                this.lastDrawnPos = this.cursorPos;
                }

            }

        protected override void OnMouseMove(MouseEventArgs e)
            {
            base.OnMouseMove(e);
            SetCursor(e.Location);
            }

        private void SetCursor(Point loc)
            {
            this.cursorPos = loc;
            foreach (Point pt in this.snapPoints)
                {
                double deltaX = loc.X - pt.X;
                double deltaY = loc.Y - pt.Y;
                double radius = Math.Sqrt((deltaX * deltaX) + (deltaY * deltaY));
                if (radius < snapLimit)
                    {
                    this.cursorPos = pt;
                    break;
                    }
                }
            if (lastDrawnPos != this.cursorPos)
                {
                this.drawCursor = true;
                this.Invalidate();
                }
            }

        protected override void OnSizeChanged(EventArgs e)
            {
            base.OnSizeChanged(e);
            this.snapPoints.Clear();
            for (int y = 0; y <= this.ClientRectangle.Height; y += 50)
                {
                for (int x = 0; x <= this.ClientRectangle.Width; x += 50)
                    {
                    this.snapPoints.Add(new Point(x, y));
                    }
                }
            }
        }
    }