Обновите чертеж, не удаляя предыдущий

Я создал это в рамках метода рисования

private void draws() { Bitmap bmp = new Bitmap(pictureBox17.Width, pictureBox17.Height); using (Graphics g = Graphics.FromImage(bmp)) { //define area do pictureBox17 e preenche a branco Brush brush = new SolidBrush(Color.White); Rectangle area = new Rectangle(0, 0, pictureBox17.Width, pictureBox17.Height); g.FillRectangle(brush, area); //desenha as linhas do rectangulo g.DrawLine(new Pen(Color.Black), esp, esp, esp, yWcorrigidoesp); // some more lines } pictureBox17.Image = bmp; } 

И он рисует именно то, что я хочу. Но представьте себе, что после этого я хочу обновить точно такой же рисунок, добавив несколько строк, не имея необходимости рисовать все снова, возможно ли это? Очевидно, я использую метод

 draws(); 

А потом я хочу что-то добавить, какие-нибудь советы?

Способ сделать это – создать class DrawAction который содержит все данные, необходимые для вещей, которые вы хотите нарисовать: данные Point , Pen или Brush и т. Д.

Затем вы создаете и управляете List drawActions а затем у вас есть выбор:

  • Вы либо делаете весь рисунок «живым» в событии Paint в PictureBox либо в Panel (или любом элементе управления с событием Paint ), перебирая список.

  • .. Или вы добавляете новые действия в Bitmap Image вы создаете.

На самом деле лучше: вы ожидаете сделать динамический рисунок, скажем, с помощью действий пользователя? Вы хотите вариант отмены / повтора? Тогда живой рисунок на контрольной поверхности немного лучше подходит.

Или список вещей, которые нужно сделать фиксированным или получить из фиксированного набора данных и предназначенный для сохранения на диске. Это больше похоже на рисование в bitmap.

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

Примечание . Ключ к материалу чертежа состоит в том, чтобы сохранить данные чертежа в списке, чтобы вы могли использовать его, когда вам это нужно, развернуть и удалить список и даже изменить его: было бы простым двухстрочным обойти все действия и изменить Color или Width или LineStyle Pen или переместить Points немного и т. д. и т. д.!

Когда вы создаете class DrawAction он помогает, если вы можете решить, какие действия вам понадобятся. Если вы не можете, вы все равно можете пойти на более расширенный class с достаточным количеством членов, чтобы работать со всеми многочисленными параметрами, предлагаемыми classом Graphics : Drawxx , Fillxxx , свойствами Pen , Colors возможно, даже с увеличением.

Для начала введите Type, List float PenWidth и Color ..

Ниже приведен пример с простым classом, событием Paint , кодом для добавления нескольких тестовых действий и both :

  • Кнопка для живого рисования и ..
  • ..one применить действие для применения действий к растровому Image PictureBox .

Данные теста – одна Line и один набор Polylines .

Вы должны начать улучшаться, Enum со всеми типами действий рисования, которые вы хотите использовать! Это будет намного лучше и легче понять тип Rectangle, FilledRectangle, Ellipse, FilledEllipse, Line, Lines, Polygon, FilledPolygon, Text, Curve, Curves я закодировал 😉 Типы могут включать Rectangle, FilledRectangle, Ellipse, FilledEllipse, Line, Lines, Polygon, FilledPolygon, Text, Curve, Curves а затем некоторые. С небольшим дополнительным вы также можете работать с Image, GraphicsPath, Spline .. И другие данные могут управлять Rotation, Scaling, Gradients, Transparency т. Д.

 List actions = new List(); public class DrawAction { public char type { get; set; } // this should be an Enum! public Color color { get; set; } public float penWidth { get; set; } // only one of many Pen properties! public List points { get; set; } // use PointF for more precision public DrawAction(char type_, Color color_, float penwidth_) { type = type_; color = color_; penWidth = penwidth_; points = new List(); } } private void pictureBox1_Paint(object sender, PaintEventArgs e) { Draw(e.Graphics, actions); } public void Draw(Graphics G, List actions) { foreach (DrawAction da in actions) if (da.type == 'L' && da.points.Count > 1) using (Pen pen = new Pen(da.color, da.penWidth)) G.DrawLine(pen, da.points[0], da.points[1]); else if (da.type == 'P' && da.points.Count > 1) using (Pen pen = new Pen(da.color, da.penWidth)) G.DrawLines(pen, da.points.ToArray()); // else.. } private void button1_Click(object sender, EventArgs e) { AddTestActions(); pictureBox1.Invalidate(); } private void button2_Click(object sender, EventArgs e) { AddTestActions(); Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height); using (Graphics G = Graphics.FromImage(bmp)) Draw(G, actions); pictureBox1.Image = bmp; } void AddTestActions() { actions.Add(new DrawAction('L', Color.Blue, 3.3f)); actions[0].points.Add(new Point(23, 34)); actions[0].points.Add(new Point(23, 134)); actions.Add(new DrawAction('P', Color.Red, 1.3f)); actions[1].points.Add(new Point(11, 11)); actions[1].points.Add(new Point(55, 11)); actions[1].points.Add(new Point(55, 77)); actions[1].points.Add(new Point(11, 77)); } 

Результат для обоих выглядит одинаково:

введите описание изображения здесь

Попробуйте создать Bitmap вне функции, чтобы сохранить его, то, как вы это делаете, теперь имеет элемент Bitmap после завершения функции.

вы могли бы сделать что-то вроде

 Bitmap bmp = new Bitmap(pictureBox17.Width, pictureBox17.Height); private void draws() { if (bmp ==null) using (Graphics g = Graphics.FromImage(bmp)) { //define area do pictureBox17 e preenche a branco Brush brush = new SolidBrush(Color.White); Rectangle area = new Rectangle(0, 0, pictureBox17.Width, pictureBox17.Height); g.FillRectangle(brush, area); //desenha as linhas do rectangulo g.DrawLine(new Pen(Color.Black), esp, esp, esp, yWcorrigidoesp); } else { using (Graphics g = Graphics.FromImage(bmp)) { g.DrawLine(new Pen(Color.Black), esp, esp, esp, yWcorrigidoesp); } // some more lines } pictureBox17.Image = bmp; } 

Просто чтобы вы начали .. 🙂

В качестве альтернативы вы можете передать bmp в функцию draw, если вы используете этот метод для рисования нескольких BMP в разное время

  • Получить домен хоста из URL?
  • Использование ADAL C # в качестве конфиденциального пользователя / сервера Daemon / Server-to-Server - 401 Unauthorized
  • Почему переопределить operator ()?
  • В чем разница между QueueUserWorkItem () и BeginInvoke (), для выполнения асинхронной активности без необходимости возврата типов
  • что может привести к сбросу стоп-кадра (я использую «throw», а не «throw ex»)
  • Глобальная горячая клавиша в консольном приложении
  • Создание приложения ASP.NET для преобразования текста в речь
  • C #: создание унаследованного события
  • инициализация массива c
  • Пул streamов с использованием boost asio
  • Как отличается абстракция и инкапсуляция?
  • Давайте будем гением компьютера.