面板背景图像闪烁

Sea*_*son 3 c# refresh panel flicker background-image

我有一个填写父表格的小组.
我使用Timer来捕获屏幕,
并将屏幕截图设置为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();

        }
    }
Run Code Online (Sandbox Code Playgroud)

toA*_*ork 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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑

另外,我想鼓励您更多地关注您使用的资源.每当一个对象实现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();
                }
            }
    }
Run Code Online (Sandbox Code Playgroud)


Sea*_*son 6

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

class SomePanel : Panel
{
    public SomePanel()
    {
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.SetStyle(ControlStyles.UserPaint, true);
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

实际上,Visual Studio 中有一个更简单的解决方案,无需任何代码!

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