You might set DoubleBuffered
to true on your control / form. Or you could try using your own Image to create a double buffered effect.
My DoubleBufferedGraphics
class:
public class DoubleBufferedGraphics : IDisposable
{
#region Constructor
public DoubleBufferedGraphics() : this(0, 0) { }
public DoubleBufferedGraphics(int width, int height)
{
Height = height;
Width = width;
}
#endregion
#region Private Fields
private Image _MemoryBitmap;
#endregion
#region Public Properties
public Graphics Graphics { get; private set; }
public int Height { get; private set; }
public bool Initialized
{
get { return (_MemoryBitmap != null); }
}
public int Width { get; private set; }
#endregion
#region Public Methods
public void Dispose()
{
if (_MemoryBitmap != null)
{
_MemoryBitmap.Dispose();
_MemoryBitmap = null;
}
if (Graphics != null)
{
Graphics.Dispose();
Graphics = null;
}
}
public void Initialize(int width, int height)
{
if (height > 0 && width > 0)
{
if ((height != Height) || (width != Width))
{
Height = height;
Width = width;
Reset();
}
}
}
public void Render(Graphics graphics)
{
if (_MemoryBitmap != null)
{
graphics.DrawImage(_MemoryBitmap, _MemoryBitmap.GetRectangle(), 0, 0, Width, Height, GraphicsUnit.Pixel);
}
}
public void Reset()
{
if (_MemoryBitmap != null)
{
_MemoryBitmap.Dispose();
_MemoryBitmap = null;
}
if (Graphics != null)
{
Graphics.Dispose();
Graphics = null;
}
_MemoryBitmap = new Bitmap(Width, Height);
Graphics = Graphics.FromImage(_MemoryBitmap);
}
/// <summary>
/// This method is the preferred method of drawing a background image.
/// It is *MUCH* faster than any of the Graphics.DrawImage() methods.
/// Warning: The memory image and the <see cref="Graphics"/> object
/// will be reset after calling this method. This should be your first
/// drawing operation.
/// </summary>
/// <param name="image">The image to draw.</param>
public void SetBackgroundImage(Image image)
{
if (_MemoryBitmap != null)
{
_MemoryBitmap.Dispose();
_MemoryBitmap = null;
}
if (Graphics != null)
{
Graphics.Dispose();
Graphics = null;
}
_MemoryBitmap = image.Clone() as Image;
if (_MemoryBitmap != null)
{
Graphics = Graphics.FromImage(_MemoryBitmap);
}
}
#endregion
}
Using it in an OnPaint
:
protected override void OnPaint(PaintEventArgs e)
{
if (!_DoubleBufferedGraphics.Initialized)
{
_DoubleBufferedGraphics.Initialize(Width, Height);
}
_DoubleBufferedGraphics.Graphics.DrawLine(...);
_DoubleBufferedGraphics.Render(e.Graphics);
}
ControlStyles I generally set if I'm using it (you may have different needs):
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
Edit:
Ok since the data is static you should paint to an Image (before your OnPaint) and then in the OnPaint use the Graphics.DrawImage()
overload to draw the correct region of your source image to the screen. No reason to redraw the lines if the data isn't changing.