Форсировать форму для перерисовывания?

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

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

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

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

Ответ 1

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

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

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 пунктов и использует гораздо меньше памяти, чем решение бит-карты. Но вы должны решить, какой способ использовать в соответствии со сложностью чертежа.

Ответ 2

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

Это в основном, как я это сделаю:

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);
    }
}

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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