Search code examples
c#refreshbackground-imagepanelflicker

Panel background image flickering


I've a Panel which fills the parent Form.
And I used a Timer to capture screen ,
and set the screenshot as background image of Panel periodically.

However, it runs into crazy flickering. What can I do to solve it?

//Part of code
 public partial class Form1 : Form
    {

        DxScreenCapture sc = new DxScreenCapture();

        public Form1()
        {
            InitializeComponent();

            panelMain.BackgroundImageLayout = ImageLayout.Zoom;
         }

        private void Form1_Load(object sender, EventArgs e)
        {
        }



        void RefreshScreen()
        {
            Surface s = sc.CaptureScreen();

            DataStream ds = Surface.ToStream(s, ImageFileFormat.Bmp);
            panelMain.BackgroundImage = Image.FromStream(ds);

            s.Dispose();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            RefreshScreen();

        }
    }

Solution

  • Try using a double buffered panel. Inherit panel, set DoubleBuffered to true and use that panel instead of default panel:

        namespace XXX
        {
            /// <summary>
            /// A panel which redraws its surface using a secondary buffer to reduce or prevent flicker.
            /// </summary>
            public class PanelDoubleBuffered : System.Windows.Forms.Panel
            {
                public PanelDoubleBuffered()
                    : base()
                {
                    this.DoubleBuffered = true;
                }
            }
        }
    

    EDIT

    Additionally I want to encourage you to take care a little more about the resources you use. Whenever an object implements the IDisposable interface - dispose the object when not needed any more. This is very important when dealing with unmanaged resources, such as streams!

        void RefreshScreen()
        {
                using (Surface s = sc.CaptureScreen())
                {
                    using (DataStream ds = Surface.ToStream(s, ImageFileFormat.Bmp))
                    {
                        Image oldBgImage = panelMain.BackgroundImage;
                        panelMain.BackgroundImage = Image.FromStream(ds);
                        if (oldBgImage != null)
                            oldBgImage.Dispose();
                    }
                }
        }