Рисование в двух картинках - PullRequest
0 голосов
/ 22 мая 2018

Я создал две картинки в моем приложении Windows.Я хочу нарисовать их обоих, используя FillEllipse (), но по какой-то причине я могу рисовать только в первом pictureBox.Я верю, что проблема в том, что я не понимаю, как работают события.Вот код:

public Form1()
    {
        InitializeComponent();
        pictureBox1.Paint += new PaintEventHandler(this.pictureBox1_Paint);
        pictureBox2.Paint += new PaintEventHandler(this.pictureBox2_Paint);
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        Graphics gr = e.Graphics;
        Point p1 = pictureBox1.Location;
        gr.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p1.X + 40, p1.Y + 40, 20, 20));
        gr.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p1.X + 40, p1.Y + 80, 20, 20));
        gr.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p1.X + 80, p1.Y + 40, 20, 20));
        gr.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p1.X + 80, p1.Y + 80, 20, 20));
    }

    private void pictureBox2_Paint(object sender, PaintEventArgs e)
    {
        Graphics br = e.Graphics;
        Point p2 = pictureBox2.Location;
        br.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p2.X + 40, p2.Y + 40, 20, 20));
        br.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p2.X + 40, p2.Y + 80, 20, 20));
        br.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p2.X + 80, p2.Y + 40, 20, 20));
        br.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p2.X + 80, p2.Y + 80, 20, 20));
    }

Ответы [ 3 ]

0 голосов
/ 22 мая 2018

Вы рисуете в картинке Box2.Ваша проблема заключается в том, что вы рисуете вне области просмотра, потому что вы рисуете в местоположении pictureBox2 на форме, но внутри окна рисунка.pictureBox2.Location указывает на положение поля в форме.Если этот блок находится в позиции x = 240, y = 240, вы рисуете ВНУТРИ блока в этих позициях.Если у вашего поля только w = 50, h = 50, вы не увидите то, что рисуете, потому что оно справа и снизу

0 голосов
/ 22 мая 2018

PaintEventArgs e.Graphics дает вам DeviceContext элемента управления (считайте его ссылкой на графическую поверхность элемента управления) и набор инструментов, которыеможет использоваться для выполнения графических операций в этом контексте.

При использовании e.Graphics все рисунки находятся внутри базовой поверхности, на которую ссылается графический объект (a PictureBox ClipRectangle вв этом случае).
Все координаты относятся к этой области.

Таким образом, вам просто нужно указать положение и размер чертежа, используя клиентскую область элемента управления в качестве единственной ссылки.Размеры области рисования также сообщаются с помощью e.Graphics.ClipBounds (выражается в PageUnits ) и элемента управления ClientRectangle (выражается в Pixels).
ClientRectangle - это область элемента управления, которая исключает не клиентские элементы, такие как Borders, Menus, ScrollBars, TitleBar и т. Д .;это «внутреннее тело».

Однако определение клиентской области может измениться относительно внутренней структуры элемента управления (например, представьте элемент управления ListView или ComboBox).

Событие Paint() элемента управления вызывается каждый раз, когда элемент управления должен перерисоваться.
Он всегда вызывается после первого создания элемента управления.
Послечто он может быть запущен, когда, например, элемент управления по некоторым причинам «скрыт» другим элементом управления / окном или когда Form, содержащий его, свернут.

Его можно поднять«вручную», вызывая метод Invalidate () элемента управления.
Это, вероятно, предпочтительный способ заставить элемент управления перерисовывать себя, потому что метод Invalidate() позволяет указать определенную часть (a * 1053).* или Region ) элемента управления, который требует перекраски, ограничивая рисование этой областью.

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

public Form1()
{
    InitializeComponent();
    pictureBox1.Paint += new PaintEventHandler(this.pictureBox1_Paint);
    pictureBox2.Paint += new PaintEventHandler(this.pictureBox2_Paint);
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.FillEllipse(Brushes.Red, new Rectangle(40, 40, 20, 20));
    e.Graphics.FillEllipse(Brushes.Red, new Rectangle(40, 80, 20, 20));
    e.Graphics.FillEllipse(Brushes.Red, new Rectangle(80, 40, 20, 20));
    e.Graphics.FillEllipse(Brushes.Red, new Rectangle(80, 80, 20, 20));
}

private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.FillEllipse(Brushes.Red, new Rectangle(40, 40, 20, 20));
    e.Graphics.FillEllipse(Brushes.Red, new Rectangle(40, 80, 20, 20));
    e.Graphics.FillEllipse(Brushes.Red, new Rectangle(80, 40, 20, 20));
    e.Graphics.FillEllipse(Brushes.Red, new Rectangle(80, 80, 20, 20));
}

SmoothingMode = SmoothingMode.AntiAlias используется для "prettify "приводит к графике.
Она генерирует более плавные границы.

Используемая Кисть для рисования является стандартным объектом (предоставляется системой), который не нуждается вbe Disposed().
Если вы создаете Brush с использованием одного из классов, связанных с кистью, создаваемый объект должен быть удален.

using (SolidBrush brush = new SolidBrush(Color.Red))
{
    e.Graphics.FillEllipse(brush, new Rectangle(40, 40, 20, 20));
}
0 голосов
/ 22 мая 2018

Итак, это действительно неэффективно: вы рисуете все дважды, что приводит к удвоению нагрузки.Что вам нужно сделать, так это нарисовать один раз в растровом изображении и загрузить растровое изображение в два графических блока.

https://docs.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-create-a-bitmap-at-run-time

Однако, если работа с растровыми изображениями не позволит вам достичь чего-либоэто вы пытаетесь сделать, напишите пользовательский элемент управления.Хотя это и не улучшит производительность, но по крайней мере остановит дублирование кода.

https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/creating-a-wf-control-design-time-features

Bitmap img= new Bitmap(100, 100);
Point p1 = pictureBox1.Location;
Graphics gr = Graphics.FromImage(img);
gr.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p1.X + 40, p1.Y + 40, 20, 20));
gr.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p1.X + 40, p1.Y + 80, 20, 20));
gr.FillEllipse(new SolidBrush(Color.Red), new Rectangle(p1.X + 80, p1.Y + 40, 20, 20));


picturebox1.Image = img;
picturebox2.Image = img;
...