强制表格重绘?

时间:2010-03-04 05:04:54

标签: c# winforms

在C#WinForms中 - 我正在绘制一个实时的折线图,它基于每500毫秒通过串口接收的数据。

e.Graphics.DrawLine逻辑位于表单的OnPaint处理程序中。

一旦我从串口收到数据,我需要调用一些导致表单重绘的东西,以便调用OnPaint处理程序。我试过这个.Refresh和this.Invalidate,会发生的事情是我丢失了以前在表单上绘制的内容。

有没有其他方法可以实现这一目标而不会丢失表格中的内容?

5 个答案:

答案 0 :(得分:22)

重点是你应该考虑将绘图数据存储在某个地方。如前所述,缓冲位图是一种解决方案。但是,如果您没有太多绘图,有时将绘图数据存储在变量或数组中并重绘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点,并且使用的内存比缓冲区位图解决方案少得多。但是你应该根据绘图的复杂性决定使用哪种方式。

答案 1 :(得分:7)

正如重新运行所说,您需要缓冲表单(因为您在绘制数据后似乎丢弃了数据)。

这基本上就是我这样做的方式:

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

也就是说,您可能希望缓存数据,以便在表单大小更改时更改缓冲区的大小,然后重新绘制其中的旧数据。

答案 2 :(得分:1)

解决方案可能是this.Invalidate()

答案 3 :(得分:0)

处理此问题的默认方法是创建一个内存位图并在其上绘制,然后将图片框的图像属性设置为内存位图。

答案 4 :(得分:0)

您需要在某处存储历史数据并重新绘制它。

这比缓存和剪辑位图要容易得多。