Das Problem scheint in der Methode SnapToGrid zu liegen.
// Berechnen der nächsten Rasterposition
int xSnap = (point.X + gridSize / 2) / gridSize * gridSize;
int ySnap = (point.Y + gridSize / 2) / gridSize * gridSize;
Wenn du das gridsize / 2 weglässt
int xSnap = (point.X) / gridSize * gridSize;
int ySnap = (point.Y) / gridSize * gridSize;
dann sollte es genau auf dem darunterliegenden Feld einrasten. In der OnPaint Methode
// Wenn das Ziehen abgeschlossen ist, fügen Sie das Label hinzu
using (Brush brush = new SolidBrush(Color.LightBlue))
{
Point snapPoint = SnapToGrid(originalLocation);
e.Graphics.FillRectangle(brush, snapPoint.X, snapPoint.Y, gridSize, gridSize);
}
setzt du außerdem die neue Position auf die ursprüngliche Position was der Grund dafür ist das das Element auf seine ursprüngliche Position zurück rutscht. Hier ist ein überarbeitetes Beispiel.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace GridWithDragDrop
{
public class MainForm : Form
{
private const int gridSize = 50;
private Point startPoint;
private Point originalLocation;
private bool isDragging;
private Point newLocation;
public MainForm()
{
this.Text = "Grid with Drag & Drop";
this.Size = new Size(600, 400);
this.DoubleBuffered = true;
// Ereignisbehandlung für das Zeichnen des Rasters und das Verschieben der Elemente
this.Paint += MainForm_Paint;
this.MouseDown += MainForm_MouseDown;
this.MouseMove += MainForm_MouseMove;
this.MouseUp += MainForm_MouseUp;
}
private void MainForm_Paint(object sender, PaintEventArgs e)
{
// Raster zeichnen
using (Pen gridPen = new Pen(Color.LightGray))
{
for (int x = 0; x < this.ClientSize.Width; x += gridSize)
{
e.Graphics.DrawLine(gridPen, x, 0, x, this.ClientSize.Height);
}
for (int y = 0; y < this.ClientSize.Height; y += gridSize)
{
e.Graphics.DrawLine(gridPen, 0, y, this.ClientSize.Width, y);
}
}
}
private void MainForm_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
startPoint = e.Location;
originalLocation = startPoint;
isDragging = true;
}
}
private void MainForm_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
newLocation = SnapToGrid(e.Location);
this.Invalidate(); // Neuzeichnen erzwingen, um das alte Label zu löschen
startPoint = newLocation;
}
}
private void MainForm_MouseUp(object sender, MouseEventArgs e)
{
if (isDragging)
{
newLocation = SnapToGrid(e.Location);
this.Invalidate(); // Neuzeichnen erzwingen, um das alte Label zu löschen
isDragging = false;
}
}
private Point SnapToGrid(Point point)
{
// Berechnen der nächsten Rasterposition
int xSnap = (point.X ) / gridSize * gridSize;
int ySnap = (point.Y ) / gridSize * gridSize;
return new Point(xSnap, ySnap);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (isDragging)
{
// Zeichnen des Labels während des Ziehens
using (Brush brush = new SolidBrush(Color.LightBlue))
{
e.Graphics.FillRectangle(brush, startPoint.X, startPoint.Y, gridSize, gridSize);
}
}
else
{
// Wenn das Ziehen abgeschlossen ist, fügen Sie das Label hinzu
using (Brush brush = new SolidBrush(Color.LightBlue))
{
Point snapPoint = SnapToGrid(newLocation);
e.Graphics.FillRectangle(brush, snapPoint.X, snapPoint.Y, gridSize, gridSize);
}
}
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}