Domanda

Sto lavorando su un programma che disegna una semplice griglia di punti. Vorrei che il mouse per scattare tra i punti sulla griglia di partenza, alla fine di disegnare linee sulla griglia.

Ho un metodo che prende nella posizione corrente del mouse (X, Y) e calcola la coordinata della griglia più vicino.

Quando creo un evento e si tenta di spostare il mouse per il nuovo coordinare l'intero sistema diventa a scatti. Il mouse non scatta senza problemi tra i punti della griglia.

Ho copiato un esempio di codice di seguito per illustrare ciò che sto cercando di fare. Qualcuno ha qualche consiglio che mi potrebbe offrire quanto a come posso eliminare il nervosismo all'interno del movimento 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;
        }
    }
}
È stato utile?

Soluzione

Credo di capire dove stai venendo. Hai semplicemente bisogno di essere qualche delta lontano dal punto di snap originale (il sinistro del mouse) prima di scattare al nuovo punto.

Ecco 50 righe di codice che illustrano quello che voglio dire: (Avviare un nuovo progetto VB.NET, aggiungere un nuovo modulo, copiare e incollare il codice, aggiungere un riferimento, del sistema, System.Drawing e 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

Altri suggerimenti

Non modificare la posizione del cursore. Non è necessario.

Invece, disegnare come se fosse scattato alla griglia. Quando l'utente fa clic da qualche parte, basta disegnare la linea dai punti della griglia più vicini.

Per esempio, se l'utente fa clic su (197.198), ma si sa che il punto più vicino è in realtà (200,200), basta tracciare una linea a (200,200) invece di (197.198).

E per favore, non si scherza con il reale posizione del cursore.


Non so se c'è un modo per nascondere il cursore del mouse. Se c'è, si può nascondere e disegnare voi stessi, senza modificare la posizione reale .

Il mouse mantiene scattare allo stesso punto, se si tenta di spostare - perché è ancora più vicino a quel punto ... Se si sposta il mouse a destra, spostare il cursore sul punto a sinistra di quello attuale, invece ricalcolare alla corrente. Applicare per gli altri 3 direzioni ...

Non vorrei raccomandare questo comportamento, però, causerà un sacco di irritazione. Snap i controlli alla rete, non il mouse.

Sono d'accordo con ruijoel, non si scherza con la posizione del cursore. E 'meglio avere una croce o un anello che viene disegnata in corrispondenza del punto gioco da ragazzi per mostrare all'utente che punto è quello che andranno a ruba ad un evento click.

Per far funzionare tutto questo ben si consiglia di guardare XOR-disegno in modo tale elemento viene cancellata non appena si passa a un nuovo punto di scatto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top