在C#WinForms中 - 我正在繪製一個實時線形圖,它基於每500毫秒通過串行端口接收的數據。強制形式重繪?
e.Graphics.DrawLine邏輯位於窗體的OnPaint處理程序中。
一旦我從串口收到數據,我需要調用一些導致窗體重繪的事件,以便調用OnPaint處理程序。我試過這個。刷新和this.Invalidate,會發生什麼,我失去了以前在窗體上繪製的任何東西。
有沒有另一種方法來實現這一點,而不會丟失表單上繪製的內容?
在C#WinForms中 - 我正在繪製一個實時線形圖,它基於每500毫秒通過串行端口接收的數據。強制形式重繪?
e.Graphics.DrawLine邏輯位於窗體的OnPaint處理程序中。
一旦我從串口收到數據,我需要調用一些導致窗體重繪的事件,以便調用OnPaint處理程序。我試過這個。刷新和this.Invalidate,會發生什麼,我失去了以前在窗體上繪製的任何東西。
有沒有另一種方法來實現這一點,而不會丟失表單上繪製的內容?
問題是您應該考慮將繪圖數據存儲在某處。如前所述,緩衝位圖是一種解決方案。但是,如果您沒有太多畫圖,有時將繪圖數據存儲在變量或數組中並重新繪製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點,並使用比緩衝液位內存少得多。但是你應該根據繪圖的複雜性來決定使用哪種方式。
處理此問題的默認方法是創建一個內存位圖並在其上繪製,然後將圖片框的圖像屬性設置爲內存位圖。
正如重新運行所述,您需要緩衝您的表單(因爲您在繪製數據後似乎會丟棄數據)。
這基本上是我會怎麼做:
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()
謝謝 - 效果很好。 快速問題 - 我正在實時繪製此折線圖 - 最終我將超過屏幕上的最大可用寬度,因此我希望我在表單上繪製的線稍微向左移動,以便爲正在繪製的新座標騰出空間。有關如何做到這一點的任何建議?基本上我正在開發一個簡單的EKG類型的應用程序。 – Chris 2010-03-04 06:43:24
有很多方法可以做到這一點。例如,您可以使用e.Graphics.TranslateTransform(-x,0);這使得您繪製的所有圖形都向左移動x個像素。 – Zenya 2010-03-04 07:43:30