Переместите прямоугольник с помощью мыши

Я написал этот код:

private struct MovePoint
    {
        public int X;
        public int Y;
    }
private void Image_MouseDown(object sender, MouseEventArgs e)
    {
        FirstPoint = new MovePoint();
        FirstPoint.X = e.X;
        FirstPoint.Y = e.Y;
    }

    private void Image_MouseMove(object sender, MouseEventArgs e)
    {
        if(e.Button == MouseButtons.Left)
        {
            if(FirstPoint.X > e.X)
            {
                Rectangle.X = FirstPoint.X - e.X;
                //Rectangle.Width -= FirstPoint.X - e.X;
            } else
            {
                Rectangle.X = FirstPoint.X + e.X;
                //Rectangle.Width += FirstPoint.X + e.X;
            }

            if(FirstPoint.Y > e.Y)
            {
                Rectangle.Y = FirstPoint.Y - e.Y;
                //Rectangle.Height -= FirstPoint.Y - e.Y;
            } else
            {
                Rectangle.Y = FirstPoint.Y + e.Y;
                //Rectangle.Height += FirstPoint.Y + e.Y;
            }

            Image.Invalidate();
        }
    }
private void Image_Paint(object sender, PaintEventArgs e)
    {
        if(Pen != null) e.Graphics.DrawRectangle(Pen, Rectangle);
    }

Прямоугольник движется, но с инверсией (так быть не должно). Вы можете помочь?


person Ticksy    schedule 26.12.2011    source источник
comment
Вы никогда не задаете прямоугольнику ширину или высоту.   -  person Hans Passant    schedule 26.12.2011
comment
@Hans: Похоже, это всего лишь фрагмент. Если бы у прямоугольника не было начальной ширины и высоты, ОП не мог бы увидеть его движение (хотя и неправильно). :)   -  person Ani    schedule 26.12.2011
comment
@HansPassant: ширина и высота указаны, но я не опубликовал этот фрагмент кода   -  person Ticksy    schedule 26.12.2011


Ответы (1)


Математика в вашем обработчике перемещения мыши для перемещения прямоугольника на основе движений мыши кажется совершенно неправильной; Я думаю, вы хотите что-то вроде этого:

private void Image_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        int initialX = 0, initialY = 0; // for example.

        Rectangle.X = (e.X - FirstPoint.X) + initialX; 
        Rectangle.Y = (e.Y - FirstPoint.Y) + initialY;

        Image.Invalidate();
    }
}

Таким образом, верхний левый угол прямоугольника будет следовать за мышью, отслеживая разницу между начальным положением мыши и текущим положением мыши. Однако обратите внимание, что каждый раз, когда вы повторно щелкаете и перетаскиваете прямоугольник, он возвращается в свое исходное положение.

Если вместо этого вы хотите, чтобы прямоугольник "запоминал" свое положение при нескольких операциях щелчка и перетаскивания (т.е. не был повторно инициализирован в исходное положение при нажатии мыши), вы можете сделать:

private void Image_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        // Increment rectangle-location by mouse-location delta.
        Rectangle.X += e.X - FirstPoint.X; 
        Rectangle.Y += e.Y - FirstPoint.Y; 

        // Re-calibrate on each move operation.
        FirstPoint = new MovePoint { X = e.X, Y = e.Y };

        Image.Invalidate();
    }
}

Еще одно предложение: нет необходимости создавать свой собственный тип MovePoint, когда уже есть тип System.Drawing.Point. Также вообще старайтесь не создавать изменяемые структуры.

person Ani    schedule 26.12.2011
comment
Большое спасибо! Особенно во второй части ответа (думал как исправить этот баг со сбросом позиции). - person Ticksy; 26.12.2011