winform程序背景图闪屏问题

问题背景

在工控项目中, 往往需要加载一个背景图像用于模拟设备或图纸, 在其上需要动态放置一些标签或按钮,
通常的做法是, 使用Panel组件通过设置 BackgroundImage 属性加载背景图, 经常碰到的问题是, 窗口做resize或动态增加/删除Label时, 界面会有非常明显的屏闪现象.

public void loadPicture(string fileName)
{
    pnlContainer.BackgroundImageLayout = ImageLayout.Stretch;
    pnlContainer.BackgroundImage = null; 
    if (string.IsNullOrWhiteSpace(fileName) == false)
    {
        pnlContainer.BackgroundImage = Image.FromFile(fileName); 
    }
}

方案: 使用 pictureBox 加载背景图

在容器panel中新增一个 pictureBox 组件, 使用 pictureBox 组件来加载背景图像, pictureBox 组件本身做过优化, 能很好的解决屏闪问题. 唯一问题是 pictureBox 组件不能作为容器, 动态生成的 label 组件的 z-order 方向, 总是被 pictureBox 覆盖住, 所以在动态生成 label 后, pictureBox1.SendToBack(), 确保 pictureBox1 放置到最下层.

public void loadPicture(string fileName)
{            
    pictureBox1.BackgroundImageLayout = ImageLayout.Stretch;
    pictureBox1.BackgroundImage = null;
    if (string.IsNullOrWhiteSpace(fileName) == false)
    {
        pictureBox1.BackgroundImage = Image.FromFile(fileName);
    }
}

//在调用 newManyLabels() 之后, 再调用 pictureBox1.SendToBack(), 确保 pictureBox1 放置到最下层, 形成背景效果.

方案: 使用 timer 降低 repaint 频次

窗口大小变化时,不立即刷新panel。可以使用Timer延迟刷新,比如50毫秒。这样可以合并多个大小调整导致的刷新请求,避免过度绘制和闪烁。

Timer timer = new Timer();
timer.Interval = 50;
timer.Tick += (s, e) => panel.Invalidate();

方案: 使用双缓存技术

在我的场景中没什么效果:http://csharp.tips/tip/article/852-how-to-prevent-flicker-in-winforms-controlhttps://chuxing.blog.csdn.net/article/details/38313575

你可能感兴趣的:(winform程序背景图闪屏问题)