Как нарисовать маленькую точку на каждом щелчке мыши в WinForms PictureBox - PullRequest
0 голосов
/ 02 октября 2018

У меня есть программа WinForms, в которой пользователь нажимает на PictureBox элемент управления.
Я хочу маленькую красную точку (несколько пикселей в поперечнике) каждый раз, когда пользователь щелкает.
Я также нехочу убрать любую из предыдущих точек.

Я знаю, что мне понадобится общий список эллипсов и прямоугольников, но я не уверен, как это выполнить.Как мне поступить так?

В моей программе метод pictureBox1_Click обрабатывает события щелчка мыши и возвращает положение щелчков.
Метод pictureBox1_Paint обрабатывает графику, которая должна бытьобращается на эти точки.

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

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

Возможно, вы также хотите создать другойвиды рисования точки , основанные на некоторых условиях или требованиях.
Таким образом, вам необходимо хранить и эти дополнительные свойства, а не только координаты точки.
Если это так, вам нужен специализированный объект, которыйможет предоставить эти свойства при необходимости.

Итак, вот пользовательский объект Class с некоторыми простыми свойствами, который позволяет вам определить цвет и размер точки.Для каждой из его коллекции Points.
Он также реализует интерфейс IDisposable, поскольку нам необходимо создать объект Pen для каждой нарисованной точки.И объект Pen должен быть удален (реализует IDisposable).

Чтобы выполнить рисование, вам просто нужно вызвать Control.Invalidate() (pictureBox1.Invalidate() в примере).Это вызывает перерисовку недействительных частей элемента управления, вызывая событие OnPaint().
Каждая точка (которую необходимо перекрасить) рисуется с помощью e.Graphics.DrawEllipse()

Вы можете проверить это следующим образом:

С предопределенными свойствами, используя только координату указателя мыши:

myPoints.Add(new MyPoints.DrawingPoint(e.Location));

С определенными свойствами, когда требуется что-то другое:

С размером 8x8 пикселей
newPoint.Dot = new Rectangle(e.Location, new Size(8, 8)));

С оранжевой ручкой размером 2 пикселя
newPoint.DrawingPen = new Pen(Color.Orange, 2);

Добавитьэтот новый Указатель на коллекцию
myPoints.DrawingPoints.Add(newPoint);

РЕДАКТИРОВАТЬ:
Добавление метода Clear() к основному объекту, используетсяDispose() текущий список очков и создать новый пустой список:
MyPoints.Clear();

Пример реализации:

MyPoints myPoints = new MyPoints();

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    //Use default property values
    //myPoints.Add(new MyPoints.DrawingPoint(e.Location));

    MyPoints.DrawingPoint newPoint = new MyPoints.DrawingPoint();
    newPoint.Dot = new Rectangle(e.Location, new Size(4, 4));
    newPoint.DrawingPen = new Pen(Color.Red, 2);
    myPoints.DrawingPoints.Add(newPoint);
    ((Control)sender).Invalidate();
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    foreach (MyPoints.DrawingPoint mypoint in myPoints.DrawingPoints) {
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        e.Graphics.DrawEllipse(mypoint.DrawingPen, mypoint.Dot);
    }
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    myPoints.Dispose();
}

Контейнер класса объектов Point:

internal class MyPoints : IDisposable
{
    bool IsDisposed = false;
    public MyPoints() => DrawingPoints = new List<DrawingPoint>();

    public List<DrawingPoint> DrawingPoints { get; set; }
    public void Add(DrawingPoint NewPoint)
    {
        if (NewPoint.Dot.Size.Width > 1 && NewPoint.Dot.Size.Height > 1)
            DrawingPoints.Add(NewPoint);
    }

    public void Clear()
    {
        this.Dispose();
        this.DrawingPoints.Clear();
        this.DrawingPoints = new List<DrawingPoint>();
    }

    public void Remove(Point point)
    {
        Remove(this.DrawingPoints.Select((p, i) => { if (p.Dot.Contains(point)) return i; return -1; }).First());
    }

    public void Remove(int Index)
    {
        if (Index > -1)
        {
            this.DrawingPoints[Index].Delete();
            this.DrawingPoints.RemoveAt(Index);
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected void Dispose(bool IsSafeDisposing)
    {
        if (IsSafeDisposing && (!this.IsDisposed) && (this.DrawingPoints.Count > 0))
        {
            foreach (DrawingPoint dp in this.DrawingPoints)
                if (dp != null) dp.Delete();
        }
    }

    public class DrawingPoint
    {
        Pen m_Pen = null;
        Rectangle m_Dot = Rectangle.Empty;

        public DrawingPoint() : this(Point.Empty) { }
        public DrawingPoint(Point newPoint)
        {
            this.m_Pen = new Pen(Color.Red, 1);
            this.m_Dot = new Rectangle(newPoint, new Size(2, 2));
        }

        public Pen DrawingPen { get => this.m_Pen; set => this.m_Pen = value; }
        public Rectangle Dot { get => this.m_Dot; set => this.m_Dot = value; }

        public void Delete()
        {
            if (this.m_Pen != null) this.m_Pen.Dispose();
        }
    }
}

Вот как он может работать, изменяя свои свойства при необходимости:

DottedColors1

0 голосов
/ 02 октября 2018

Я придумал простое решение для своей проблемы. Я составил список прямоугольников:

        List<Rectangle> rects = new List<Rectangle>();

И добавил прямоугольники при каждом клике:

        private void pictureBox1_Click(object sender, MouseEventArgs e)
        {
             rects.Add(new Rectangle(e.Location, new Size(4,4)));
        }

И нарисовал точки:

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        foreach (var rect in rects)
        {

            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.DrawEllipse(magenta,rect);
        }
    }

И добавлен метод очистки рисунков с помощью rects.Clear ()

0 голосов
/ 02 октября 2018

В основном вы должны использовать GDI +

Проверьте код ниже:

    private void pictureBox1_Click(object sender, EventArgs e)
    {
        Graphics g = Graphics.FromImage(pictureBox1.Image);
        Pen p = new Pen(Color.Red, 3);

        var cursorPosition = pictureBox1.PointToClient(Cursor.Position);
        g.DrawEllipse(p, cursorPosition.X, cursorPosition.Y, 15, 15);

        MyCircles.Add(cursorPosition);
        pictureBox1.Refresh();
    }


    List<Point> MyCircles = new List<Point>();

    private void pictureBox1_DoubleClick(object sender, EventArgs e)
    {
        foreach (var item in MyCircles)
        {
            MessageBox.Show($"One circle was created: X:{item.X}, Y:{item.Y}");
        }
    }

Список MyCircles предназначен только для тех случаев, когда вы хотите сохранить круги, чтобы потом отобразить изображение с кружками позже, идвойной щелчок - это пример его использования (я имею в виду постоянство, потому что круги не покинут изображение, пока вы не закроете свое приложение).Проверьте другие g методы для рисования линий, прямоугольников или чего-либо еще.(Использует пространство имен System.Drawing)

...