閑着沒事,准備做一個類似於TeeChart的自定義控件,結果第一步的繪圖就把我給難倒了,雖然早就知道GDI繪圖的閃爍問題很坑,但是卻沒有想到如此之坑,折騰了兩天,才找到解決方法。
首先在窗體加載的時候,加入雙緩存,說實話以前一直沒覺得這個雙緩存有什么用,不過這次總算是有了點兒效果。
DoubleBuffered = true; SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
下面是一個例子,我准備畫一個簡單的坐標系。這個方法會獲得一個自定義的位圖,將這個位圖直接賦值給窗體的背景圖片,或者PictureBox控件也可以。
/// <summary> /// 繪制界面 /// </summary> private Bitmap DrawGDI() { var bmp = new Bitmap(Width, Height); var pen = new Pen(Color.Black, 1.0f); Graphics g = Graphics.FromImage(bmp); var p1 = new Point(20, 10); var p2 = new Point(20, Height - 25); var p3 = new Point(Width - 10, Height - 25); g.DrawLines(pen, new[] { p1, p2, p3 }); g.DrawString("0", Font, Brushes.Black, 10, Height - 20); return bmp; }
我這里是直接在重繪方法里面給背景圖片直接賦值了。
/// <summary> /// 重繪 /// </summary> protected override void OnPaint(PaintEventArgs e) { BackgroundImage = DrawGDI(); base.OnPaint(e); }
做完這些之后,我驚訝的發現GDI繪制出的圖居然不閃了。當然了,這個方法的可移植性還不太清楚,歡迎大家討論。