面板背景图像闪烁

时间:2014-02-19 07:08:00

标签: c# refresh background-image panel flicker

我有一个填充父表格的面板 我使用计时器来捕获屏幕,
并定期将屏幕截图设置为Panel的背景图片

然而,它会遇到疯狂的闪烁。我能做些什么来解决它?

//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();

        }
    }

3 个答案:

答案 0 :(得分:7)

尝试使用双缓冲面板。继承面板,将DoubleBuffered设置为true并使用该面板而不是默认面板:

    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;
            }
        }
    }

修改

此外,我想鼓励您更多地关注您使用的资源。每当一个对象实现IDisposable接口时 - 在不再需要时处置该对象。在处理非托管资源(例如流!)时,这非常重要。

    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();
                }
            }
    }

答案 1 :(得分:3)

在Visual Studio中实际上有一个不需要代码的简单解决方案!

如果您转到解决方案资源管理器,然后双击您的表单( Form1 ),则会弹出一个列表(如果它没有弹出您必须右键单击表单并转到属性并再次双击)。然后,转到 DoubleBuffered 并将其更改为 True

答案 2 :(得分:2)

我自己从其他网站找到答案。它在面板上设置了一些 ControlStyles ,如下面的代码所示。并且不再闪烁。

class SomePanel : Panel
{
    public SomePanel()
    {
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.SetStyle(ControlStyles.UserPaint, true);
    }
}