Форму Силы Перерисовать? - PullRequest
24 голосов
/ 04 марта 2010

В C # WinForms - я рисую линейную диаграмму в режиме реального времени, основанную на данных, получаемых через последовательный порт каждые 500 мс.

Логика e.Graphics.DrawLine находится в обработчике формы OnPaint.

Как только я получаю данные от последовательного порта, мне нужно вызвать что-то, что заставляет форму перерисовываться так, чтобы вызывался обработчик OnPaint. Я пробовал this.Refresh и this.Invalidate, и в результате я теряю то, что было нарисовано ранее в форме.

Есть ли другой способ достичь этого, не потеряв то, что было нарисовано в вашей форме?

Ответы [ 5 ]

22 голосов
/ 04 марта 2010

Дело в том, что вы должны подумать о том, чтобы где-то хранить свои данные чертежа. Как уже говорилось, буферное растровое изображение является решением. Однако, если вам не нужно много рисовать, иногда проще и лучше сохранить данные чертежа в переменной или массиве и перерисовать все в событии OnPaint.

Предположим, вы получили некоторые точечные данные, которые должны быть добавлены к графику. Ель всего, что вы создаете пункт Список:

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

Затем каждый раз, когда вы получаете новую точку, вы добавляете ее в список и обновляете форму:

points.Add(newPoint);
this.Refresh();

В событии OnPaint введите следующий код:

private void Form_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawLines(Pens.Red, points);
}

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

7 голосов
/ 04 марта 2010

Как уже было сказано при повторном запуске, вам нужно буферизовать вашу форму (так как кажется, что вы отбрасываете данные после того, как их нарисовали).

Вот как я бы это сделал:

private Bitmap buffer;

// When drawing the data:
if (this.buffer == null)
{
    this.buffer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
}

// then draw on buffer
// then refresh the form
this.Refresh();

protected override void OnPaint(PaintEventArgs e)
{
    if (this.buffer != null)
    {
        e.Graphics.DrawImage(this.buffer);
    }
}

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

1 голос
/ 15 февраля 2012

Решение может быть this.Invalidate()

0 голосов
/ 04 марта 2010

Вам нужно будет где-то хранить исторические данные и просто перекрасить их.

Это будет намного проще, чем, скажем, кэширование и отсечение растровых изображений.

0 голосов
/ 04 марта 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...