Как вызвать метод, который использует PaintEventArgs и координаты переменных - PullRequest
0 голосов
/ 10 декабря 2018

Я недавно начал программировать в C#, очевидно, и пытался создать простое приложение WinForms, которое берет координаты мыши и масштабирует прямоугольник в соответствии с координатами.
Проблема, с которой я сталкиваюсь, заключается в том, что я не знаю, каквызвать метод, который использует больше аргументов (в данном случае это x, y и PaintEventArgs).Или я знаю, но я не знаю, что делать с PaintEvent.

Вот весь код, поскольку он довольно короткий и довольно простой:

using System;
using System.Drawing;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        int x = e.X; 
        int y = e.Y;
        String data = (x.ToString() + " " + y.ToString());
        DrawRect(Something, x, y);
    }

    PaintEventArgs pEventArgs;
    private void Form1_Paint(object sender, PaintEventArgs e)
    {

    }

    public void DrawRect(PaintEventArgs e, int rey, int rex)
    {
        Graphics gr = e.Graphics;
        Pen pen = new Pen(Color.Azure, 4);
        Rectangle rect = new Rectangle(0, 0, rex, rey);
        gr.DrawRectangle(pen, rect);
    }
}

Я пытаюсь вызвать функцию DrawRect, чтобы нарисовать прямоугольник с width и heightсогласно координатам мыши.Я попробовал Google и попросил друзей о помощи, но пока безуспешно.
Так как я могу позвонить DrawRect() с координатами и PaintEventArgs?

Ответы [ 4 ]

0 голосов
/ 10 декабря 2018

При рисовании на поверхности элемента управления вы всегда используете событие Paint этого элемента управления.
Никогда не пытайтесь сохранить его Graphics объект (он больше не действителен, так каккак только элемент управления становится недействительным (перекрашивается)).
Не пытайтесь использовать его PaintEventArgs каким-либо экзотическим способом.Используйте объект Graphics, на который он ссылается, только внутри события Paint.

Когда требуется более сложная процедура для рисования большего количества различных фигур, вы можете передать объект e.Graphics, предоставленныйсобытие Paint для различных методов, которые будут использовать объект e.Graphics для выполнения специализированных рисунков.


В этом примере я сохраняю координаты каждого нарисованного прямоугольника в специализированном классе(DrawingRectangle, упрощенная структура здесь), и я использую List<DrawingRectangle>() для доступа к этим ссылкам.

Когда событие MouseDown сообщает, что левая кнопка нажата на поверхности элемента управления,e.Location сохраняется как DrawingRectangle.Location (это значение может изменяться в зависимости от направления указателя мыши) и DrawingRectangle.StartPoint (контрольная мера, которая не изменяется).

КогдаПри перемещении мыши текущие значения e.Location координат вычитаются из сохраненных координат начальной точки Rectangle (плюс некоторые вычисления, которые позволяют нарисовать Rectangle со всех сторон).Эта мера является размером прямоугольника.

Каждый раз, когда обнаруживается левый MouseDown, в список добавляется новый элемент класса.

Чтобы удалить прямоугольник из чертежа, вам просто нужно удалить его ссылкуиз Списка и Invalidate() Элемент управления, который предоставляет поверхность для рисования.
Чтобы очистить поверхность для рисования, очистите List<DrawingRectangle>() (DrawingRects.Clear()) и вызовите Invalidate().

Некоторые другие примеры здесь:
Прозрачные перекрывающиеся круговые индикаторы хода выполнения
Классы GraphicsPath и Matrix
Соединение различных фигур
Рисование прозрачного / полупрозрачногоПользовательские элементы управления

Drawing Rectangles

List<DrawingRectangle> DrawingRects = new List<DrawingRectangle>();

public class DrawingRectangle
{
    public Point Location { get; set; }
    public Size Size { get; set; }
    public Point StartPosition { get; set; }
    public Color DrawingcColor { get; set; } = Color.LightGreen;
    public float PenSize { get; set; } = 3f;

}

private void form1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left) {
        DrawingRects.Add(new DrawingRectangle() {
            Location = e.Location, Size = Size.Empty, StartPosition = e.Location
        });
    }
}

private void form1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        DrawingRectangle rect = DrawingRects.Last();
        if (e.Y < rect.StartPosition.Y) { rect.Location = new Point(rect.Location.Y, e.Y); }
        if (e.X < rect.StartPosition.X) { rect.Location = new Point(e.X, rect.Location.Y); }

        rect.Size = new Size(Math.Abs(rect.StartPosition.X - e.X), Math.Abs(rect.StartPosition.Y - e.Y));
        DrawingRects[DrawingRects.Count - 1] = rect;
        this.Invalidate();
    }
}

private void form1_Paint(object sender, PaintEventArgs e)
{
    if (DrawingRects.Count == 0) return;
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    foreach (var rect in DrawingRects) {
        using (Pen pen = new Pen(rect.DrawingcColor, rect.PenSize)) {
            e.Graphics.DrawRectangle(pen, new Rectangle(rect.Location, rect.Size));
        };
    }
}

private void btnClear_Click(object sender, EventArgs e)
{
    DrawingRects.Clear();
    this.Invalidate();
}
0 голосов
/ 10 декабря 2018

приложение, которое принимает координаты мыши и масштабирует прямоугольник в соответствии с координатами

Я ожидаю увидеть что-то вроде этого (псевдокод):

Point _point;

void Form1_MouseMove(object sender, MouseEventArgs e)
{
    ... // calculate new coordinates/scale factor/whatever here
    _point = ... ; // store results in fields
    Invalidate(); // this will cause repaint every time you move mouse
}

void Form1_Paint(object sender, PaintEventArgs e)
{
    ... // take values from fields
    e.Graphics.DrawRectangle(pen, rect); // draw
}

Этодовольно просто.Живопись - это комбинация Invalidate() звонков, которые поднимают событие рисования.Переменные, которые вы передаете, используя поля.

0 голосов
/ 10 декабря 2018

Рисование в приложении WinForms работает немного иначе, чем вы, вероятно, ожидаете.Все на экране теперь считается временным, если вы, например, сверните и восстановите свое окно, экранные данные будут стерты, и вам будет предложено перекрасить его снова (событие Paint вашего окна будет запущено системой).

Вот почему этот метод DrawRect ожидает аргумент PaintEventArgs: он должен вызываться только в обработчике события Paint.Если вы вызываете его извне (как это предлагается в другом ответе), ваши прямоугольники могут вести себя непоследовательно.

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

private Point pointToDrawRect = new Point(0,0);
public void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        int x = e.X;
        int y = e.Y;
        String data = (x.ToString() + " " + y.ToString());
        pointToDrawRect= new Point(x, y);
        Invalidate();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
         if(pointToDrawRect.X != 0 || pointToDrawRect.Y != 0)
         {
             DrawRect(e, pointToDrawRect.X, pointToDrawRect.Y);
         }
    }

    public void DrawRect(PaintEventArgs e, int rey, int rex)
    {
            using (Pen pen = new Pen(Color.Azure, 4))
            {
                Rectangle rect = new Rectangle(0, 0, rex, rey);
                e.Graphics.DrawRectangle(pen, rect);
            }
    }
0 голосов
/ 10 декабря 2018

PaintEventArgs позволяет вам получить доступ к Graphics объекту, он нужен вам, чтобы что-то нарисовать.

Если вы не хотите использовать PaintEventArgs, я предлагаю вам позвонитьCreateGraphics() метод вашего Form, и он позволит вам нарисовать прямоугольник.

Чтобы повысить производительность, я предлагаю вам использовать использование клавиш (...) {} дляобъект Graphics и объект Pen.

Вам необходимо включить System.Drawing, чтобы использовать Graphics и Pen.

Ваш код будет выглядеть следующим образомчто:

using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {
        Point _coordinates;

        public Form1()
        {
            this._coordinates = new Point();
            this.InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        public void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            this._coordinates = new Point(e.X, e.Y);
            this.Invalidate();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            // Don't draw on first Paint event
            if(this._coordinates.X != 0 && this._coordinates.Y != 0)
            {
                this.DrawRect(e);
            }
        }

        public void DrawRect(PaintEventArgs e)
        {
            using (Pen pen = new Pen(Color.Azure, 4))
            {
                Rectangle rect = new Rectangle(0, 0, this._coordinates.X, this._coordinates.Y);
                e.Graphics.DrawRectangle(pen, rect);
            }
        }
    }
}
...