Three System.Drawing methods manifest slow drawing or flickery: Solutions? or Other Options?

让人想犯罪 __ 提交于 2019-12-06 10:50:26

PictureBox already has double-buffering turned on. The only way you could perceive flicker is when you draw directly to the screen instead of using the Paint event. It isn't clear whether you do from your snippet. Buffering yourself with a bitmap would work too but isn't as efficient as the double-buffering implemented by Windows Forms.

Call its Invalidate() method when the data changes, do the drawing in the Paint event (using e.Graphics) and it won't flicker.

Try buffering your data to another bitmap before you put it in the picture box. That will eliminate the flicker.

For example:

// create this once for each graph
Bitmap buffer = new Bitmap({width}, {height});

// when the data changes
using (Graphics g = Graphics.FromImage(buffer))
{
    // ... draw using the graphics
}

// draw the buffer on the picture box's image

Are you doing the drawing on a separate thread? How many times are you drawing the data a second? Your program will feel slow if you are doing it on the main thread or are repeatedly drawing the entire bitmap a number of times a second.

Subclass your picture box and enable the double buffer option.

Public Class MyBufferedPictureBox Inherits System.Windows.Forms.PictureBox

Public Sub New()
    MyBase.New()

    Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
End Sub

End Class

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.setstyle.aspx

I would use a double buffer approach. Create a new bitmap in memory(the same size as the graph) create a graphics object of that bitmap.

Then draw whatever you want on that object.

After all the drawing is done then create another graphics object from the pictureBox and draw the in-memory-bitmap using DrawImage.

This should reduce the flickering since you draw everything ofscreen except one big draw that updates the whole image.

Hope it helps.

Luke Mcneice

[FINAL SOLUTION]

Using the paint event even with duplicate loops was fast enough!

In the End rather than duplicate the drawing loop in each event, I used the first event to also draw the other two graphs to bitmaps and then on their paint event, simply drew the bitmap.

So essentially the final solution was a combination of many of your answers.

Thank guys.

private void pictureBoxAccX_Paint(object sender, PaintEventArgs e)
        {
            bufferedploty.Clear(Color.Black);
            bufferedplotz.Clear(Color.Black);           

            for (int j = 1; j < 599; j++)
            {
                if (j > RealTimeBuffer.Count - 1) break;

                QueueEntity past = RealTimeBuffer.ElementAt(j - 1);
                QueueEntity current = RealTimeBuffer.ElementAt(j);

                e.Graphics.DrawLine(channelPen[0], j - 1, (((past.accdata.X - 0x7FFF) / 256) + 64), j, (((current.accdata.X - 0x7FFF) / 256) + 64));
                bufferedploty.DrawLine(channelPen[1], j - 1, (((past.accdata.Y - 0x7FFF) / 256) + 64), j, (((current.accdata.Y - 0x7FFF) / 256) + 64));
                bufferedplotz.DrawLine(channelPen[2], j - 1, (((past.accdata.Z - 0x7FFF) / 256) + 94), j, (((current.accdata.Z - 0x7FFF) / 256) + 94));
            }   
        }


        private void pictureBoxAccY_Paint(object sender, PaintEventArgs e)
        {        
            e.Graphics.DrawImage(BufferedBitMapy, new Point(0, 0));            
        }


        private void pictureBoxAccZ_Paint(object sender, PaintEventArgs e)
        {            
            e.Graphics.DrawImage(BufferedBitMapz, new Point(0, 0));
        }




private void AddAccPoints()
        {
            //Code for putting in New queue data Here...
            pictureBoxAccX.Invalidate();
            pictureBoxAccY.Invalidate();
            pictureBoxAccZ.Invalidate();
        }

EDIT: With this exact solution invalidating the controls can cause the event scheduling to be undefined and randomly stop drawing as the bitmap creation is done in one the event methods.

See here: Onpaint events (invalidated) changing execution order after a period normal operation (runtime)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!