visual mouseposition getposition c# grid mouse cursor-position onmousemove

c# - mouseposition - Ajustar a la rejilla del mouse bloqueando



mousemove visual basic (4)

Estoy de acuerdo con ruijoel, no te metas con la posición del cursor. Es mejor tener una cruz o un anillo que se dibuja en el punto de inicio para mostrar al usuario qué punto es el que se ajustará en un evento de clic.

Para que esto funcione bien, es posible que desee ver xor-drawing para que ese elemento se borre una vez que se mueva a un nuevo punto de ajuste.

Estoy trabajando en una aplicación que dibuja una cuadrícula de puntos simple. Me gustaría que el mouse se ajuste entre los puntos de la grilla, eventualmente para dibujar líneas en la grilla.

Tengo un método que toma la ubicación actual del mouse (X, Y) y calcula la coordenada de la cuadrícula más cercana.

Cuando creo un evento e intento mover el mouse a la nueva coordenada, todo el sistema se vuelve desigual. El mouse no se ajusta sin problemas entre los puntos de la grilla.

He copiado un ejemplo de código a continuación para ilustrar lo que intento hacer. ¿Alguien tiene algún consejo que puedan ofrecerme sobre cómo puedo eliminar el nerviosismo dentro del movimiento del mouse?

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace GridTest { public partial class Form1 : Form { Graphics g; const int gridsize = 20; public Form1() { InitializeComponent(); g = splitContainer1.Panel2.CreateGraphics(); splitContainer1.Panel2.Invalidate(); } private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e) { Drawgrid(); } private void Drawgrid() { for (int x = 0; x < splitContainer1.Panel2.ClientSize.Width; x += gridsize) { for (int y = 0; y < splitContainer1.Panel2.ClientSize.Height; y += gridsize) { g.DrawLine(Pens.Black, new Point(x, y), new Point(x + 1, y)); } } } private void splitContainer1_Panel2_MouseMove(object sender, MouseEventArgs e) { Point newPosition = new Point(); newPosition = RoundToNearest(gridsize, e.Location); Cursor.Position = splitContainer1.Panel2.PointToScreen(newPosition); } private Point RoundToNearest(int nearestRoundValue, Point currentPoint) { Point newPoint = new Point(); int lastDigit; lastDigit = currentPoint.X % nearestRoundValue; if (lastDigit >= (nearestRoundValue/2)) { newPoint.X = currentPoint.X - lastDigit + nearestRoundValue; } else { newPoint.X = currentPoint.X - lastDigit; } lastDigit = currentPoint.Y % nearestRoundValue; if (lastDigit >= (nearestRoundValue / 2)) { newPoint.Y = currentPoint.Y - lastDigit + nearestRoundValue; } else { newPoint.Y = currentPoint.Y - lastDigit; } return newPoint; } } }


El mouse sigue moviéndose al mismo punto si intenta moverlo, porque aún está más cerca de ese punto ... Si mueve el mouse hacia la izquierda, mueva el cursor al punto a la izquierda del actual en lugar de volver a calcular la corriente. Solicite las otras 3 direcciones ...

Sin embargo, no recomendaría este comportamiento, causará mucha irritación. Ajuste sus controles a la cuadrícula, no al mouse.


Creo que entiendo de dónde vienes. Simplemente necesita estar fuera del punto de referencia original (el clic izquierdo del mouse) antes de ajustar al nuevo punto.

Aquí hay 50 líneas de código que ilustran lo que quiero decir: (Inicie un nuevo proyecto VB.NET, agregue un nuevo módulo, copie y pegue el código, agregue una referencia, a System, System.drawing y System.Windows.Forms)

Imports System Imports System.Drawing Imports System.Windows.Forms Module modSnap Public Const strApplicationTitle As String = "Snap Demo" Public frmSnap As SnapForm Public ptSnap, ptStart, ptEnd As Point Public Class SnapForm Inherits Form Public Sub New() Me.Text = "Snap Demo" Me.ClientSize = New Size(800, 600) Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle Me.MaximizeBox = False Me.StartPosition = FormStartPosition.CenterScreen Me.DoubleBuffered = True End Sub Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) e.Graphics.Clear(Color.Black) For row As Integer = 20 To 780 Step 20 For col As Integer = 20 To 580 Step 20 e.Graphics.DrawEllipse(Pens.Blue, New Rectangle(row - 2, col - 2, 4, 4)) Next Next e.Graphics.DrawLine(Pens.Red, ptStart, ptEnd) End Sub Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs) MyBase.OnMouseDown(e) Dim x As Integer = CInt(e.X / 20) * 20 Dim y As Integer = CInt(e.Y / 20) * 20 ptStart = New Point(x, y) ptSnap = New Point(x, y) Windows.Forms.Cursor.Position = Me.PointToScreen(ptSnap) End Sub Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs) MyBase.OnMouseMove(e) If e.Button = Windows.Forms.MouseButtons.Left Then Dim x As Integer = CInt(e.X / 20) * 20 Dim y As Integer = CInt(e.Y / 20) * 20 '' must be some delta away from original snap point If (x < ptSnap.X - 15 Or x > ptSnap.X + 15) Or (y < ptSnap.Y - 15 Or y > ptSnap.Y + 15) Then ptSnap = New Point(x, y) ptEnd = New Point(x, y) Me.Invalidate(False) Windows.Forms.Cursor.Position = Me.PointToScreen(ptSnap) End If End If End Sub End Class Public Sub main() Try frmSnap = New SnapForm Application.Run(frmSnap) Catch ex As Exception MessageBox.Show(ex.Message, strApplicationTitle, MessageBoxButtons.OK, MessageBoxIcon.Error) Finally frmSnap.Dispose() End Try End Sub End Module


No modifique la posición del cursor. No es necesario.

En cambio, dibuja como si estuviera enganchado a la cuadrícula. Cuando el usuario hace clic en algún lugar, simplemente dibuje la línea desde los puntos de cuadrícula más cercanos.

Por ejemplo, si el usuario hace clic en (197,198), pero usted sabe que el punto más cercano en realidad es (200,200), simplemente trace una línea a (200,200) en lugar de (197,198).

Y por favor, no te metas con la posición actual del cursor.

No sé si hay alguna forma de ocultar el cursor del mouse. Si lo hay, puedes ocultarlo y dibujarlo tú mismo, sin modificar la posición real .