Драг прямоугольника
Драгом (drag) называтся возможность захватывать мышкой объекты в графическом интерфейсе (GUI) и перетаскивать их в новое место. Обычно драг осуществляется наведением на требуемый объект нажатием зажатием левой кнопки мыши и затем перемещением объекта на новое место с отпускание левой кнопки мыши в конце.
Данная задача будет использовать технику ховер прямоугольника
Введем переменные для описания прямоугольника
int posX = 50;
int posY = 50;
int rectWidth = 200;
int rectHeight = 150;
В конструкторе выполним инициализацию окна и сцены
public Form1()
{
InitializeComponent();
var timer = new System.Windows.Forms.Timer();
StartPosition = FormStartPosition.CenterScreen;
timer.Interval = 5;
timer.Start();
timer.Tick += Timer_Tick;
DoubleBuffered = true;
Paint += Form1_Paint;
//подпишемся на события мышки
MouseDown += Form1_MouseDown;
MouseUp += Form1_MouseUp;
// зададим позицию прямоугольника ровно по центру окна
posX = ClientSize.Width / 2 - rectWidth / 2;
posY = ClientSize.Height / 2 - rectHeight / 2;
}Подпишемся на события нажатия и поднятия кнопки мыши. Введем bool переменную, которая будет указывать зажата ли в данный момент мышка над нашим прямоугольником или нет.
bool isDrag = false;
private void Form1_MouseUp(object? sender, MouseEventArgs e)
{
isDrag = false;
}
private void Form1_MouseDown(object? sender, MouseEventArgs e)
{
var cursor = PointToClient(Cursor.Position);
RectangleF rect = new RectangleF(posX, posY, rectWidth, rectHeight);
if (rect.Contains(cursor))
{
//запоминает стартовую позицию прямоугольника (до драга)
startPosX = posX;
startPosY = posY;
// запоминаем позицию курсора (при старте драга)
startCursorX = cursor.X;
startCursorY = cursor.Y;
isDrag = true;
}
}
Напишем функцию отрисовки сцены:
private void Form1_Paint(object? sender, PaintEventArgs e)
{
var gr = e.Graphics;
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
gr.Clear(Color.Black);
var cursor = PointToClient(Cursor.Position);
if (isDrag) // если драг в прогрессе
{
//расчитаем разницу координат курсора (смещение драга)
var cursorDiffX = cursor.X - startCursorX;
var cursorDiffY = cursor.Y - startCursorY;
// обновим координаты прямоугольника
posX = startPosX + cursorDiffX;
posY = startPosY + cursorDiffY;
}
RectangleF rect = new RectangleF(posX, posY, rectWidth, rectHeight);
if (rect.Contains(cursor)) // проверка и отрисовка ховера
{
gr.FillRectangle(Brushes.LimeGreen, posX, posY, rectWidth, rectHeight);
}
// рисуем обводку прямоугольника
gr.DrawRectangle(Pens.White, posX, posY, rectWidth, rectHeight);
}
Проверим что получилось:

Полный код примера можно посмотреть здесь
Задания:
1. Сделать несколько разных прямоугольников, которые можно двигать
2. Сделать окружность, которую можно двигать