强制表格重绘?

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

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

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

还有另一种方法可以实现这一点而不会丢失表单上的内容吗?

关键是你应该考虑将绘图数据存储在某个地方。 如前所述,缓冲位图是一种解决方案。 但是,如果您没有太多绘制,有时将绘图数据存储在变量或数组中并重绘OnPaint事件中的所有内容会更容易也更好。

假设您收到一些应添加到图表中的点数据。 你们所有人都创造了一个点列表:

List points = new List(); 

然后,每次获得新点时,将其添加到列表并刷新表单:

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

在OnPaint事件中输入以下代码:

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

这种工作速度非常快,达到了100 000点,并且使用的内存比缓冲区位图解决方案少得多。 但是你应该根据绘图的复杂性决定使用哪种方式。

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

这基本上就是我要做的:

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

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

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

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

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

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