Это загрузка вызовов DrawLine к реальному экрану, и вполне вероятно, что это вызовет мерцание. Вы должны удвоить буфер, создав обратный буфер, сделав все, что вы рисуете на нем, затем перетащите его на экран одним вызовом DrawBitmap
по следующим строкам:
protected override void OnPaint(PaintEventArgs e)
{
using(var buffer = new Bitmap(this.Width, this.Height))
using(var gx = Graphics.FromImage(buffer))
{
// for loops to draw to gx
....
e.Graphics.DrawBitmap(buffer, ...);
}
}
Я бы также был склонен не делать именно то, что описано выше, а кэшировать этот буфер для предотвращения генерации битовой карты при каждом вызове.
Bitmap m_buffer;
Gramphic m_gx;
protected override void OnPaint(PaintEventArgs e)
{
if(m_buffer == null)
{
m_buffer = new Bitmap(this.Width, this.Height))
m_gx = Graphics.FromImage(buffer))
}
// clear the backbuffer with a FillRect
// for loops to draw to m_gx
....
e.Graphics.DrawBitmap(m_buffer, ...);
}
Вероятно, я бы даже пошел на шаг дальше, если серая часть элемента управления всегда одинакова и выполняла бы «тройной буфер», сохраняя кэшированную версию изображения с нарисованным серым, затем в OnPaint, blit что к графике, нарисуйте желтый, а затем блин на экран.
Bitmap m_buffer;
Bitmap m_backimage;
Gramphic m_gx;
protected override void OnPaint(PaintEventArgs e)
{
if(m_buffer == null)
{
m_backimage = new Bitmap(this.Width, this.Height);
var g = Graphics.FromImage(m_backImage);
// for loop to draw the grey stuff to g
....
m_buffer = new Bitmap(this.Width, this.Height))
m_gx = Graphics.FromImage(buffer))
}
m_gx.DrawImage(m_backImage);
// for loop to draw *just the yellow* to m_gx
....
e.Graphics.DrawBitmap(m_buffer, ...);
}
Вам, вероятно, придется переопределить OnResize и некоторые другие вещи, а также расширить Dispose для очистки этих объектов GDI уровня члена, но perf будет намного лучше, и он не будет мерцать.