как получить горизонтальные и вертикальные линии при наведении мыши? - PullRequest
0 голосов
/ 17 июня 2011

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

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        // "e.X" and "e.Y" are used to get MousePositionX and MousePositionY
        rect = new Rectangle(e.X, e.Y, 0, 0);
        this.Invalidate();
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        // This makes sure that the left mouse button is pressed.
        if (e.Button == MouseButtons.Left)
        {
            // Draws the rectangle as the mouse moves
            rect = new Rectangle(rect.Left, rect.Top, e.X - rect.Left, e.Y - rect.Top);
        }
        this.Invalidate();
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {

        using (Pen pen = new Pen(Color.Red, 2))
        {
            e.Graphics.DrawRectangle(pen, rect);
        }
    }

Я не знаю, где именно проблема, но могу нарисовать прямоугольник во время выполнения. Любой, пожалуйста, помогите мне с изменениями в коде.

Ответы [ 3 ]

1 голос
/ 17 июня 2011

Я бы предложил создать свой собственный элемент управления canvas ( [Edit: который наследует от PictureBox] ) с включенной двойной буферизацией. Это уменьшит мерцание при рисовании.

public partial class DrawingCanvas : PictureBox
{
    public DrawingCanvas()
    {
        InitializeComponent();
        SetStyle(
              ControlStyles.AllPaintingInWmPaint | 
              ControlStyles.OptimizedDoubleBuffer |
              ControlStyles.ResizeRedraw, true);
    }

    private Point start = new Point(0, 0);
    private Point end = new Point(0, 0);

    protected override void OnMouseDown(MouseEventArgs e)
    {
        start = e.Location;
        end = e.Location;
        Invalidate();
        base.OnMouseDown(e);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // This makes sure that the left mouse button is pressed.
        if (e.Button == MouseButtons.Left)
            end = e.Location;

        Invalidate();
        base.OnMouseMove(e);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        int top = start.Y < end.Y ? start.Y : end.Y;
        int left = start.X < end.X ? start.X : end.X;
        int width = end.X - start.X; if (width < 0) width = -width;
        int height = end.Y - start.Y; if (height < 0) height = -height;
        Rectangle rect = new Rectangle(left, top, width, height);

        using (Pen pen = new Pen(Color.Red, 2))
        {
            e.Graphics.DrawRectangle(pen, rect);
        }
    }
}

Обратите внимание, что DrawRectangle не принимает отрицательную ширину или высоту, поэтому вы должны позаботиться об этом в методе OnPaint.

Как только вы добавите этот элемент управления в свой проект, скомпилируйте проект. Ваш пользовательский элемент управления должен быть доступен в верхней части окна панели инструментов в Visual Studio. Если это не так, вы можете либо щелкнуть правой кнопкой мыши на панели инструментов и выбрать Choose Items..., чтобы добавить свой холст на панель инструментов, либо просто добавить элемент управления Panel к своему Form, открыть файл Form.Designer.cs и заменить все Panel ссылки с вашим DrawingCanvas (или любым другим именем по вашему выбору).

При настройке фонового изображения используйте свойство BackgroundImage.

1 голос
/ 17 июня 2011

Ответ Тафы работает.

Я получил только два дополнения:

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

    rect = new Rectangle(0, 0, e.X, e.Y);
    
  2. В методе MouseMove я бы использовал следующий код, чтобы не создавать новые прямоугольники при каждом перемещении мыши:

    rect.Width = e.X;  
    rect.Height = e.Y;
    
1 голос
/ 17 июня 2011

Требуются два простых изменения;

Вместо this.Invalidate() звоните pictureBox1.Invalidate().

В методе mouseMove создайте прямоугольник как;

rect = new Rectangle(0, 0, e.X, e.Y);

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

...