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-control
https://chuxing.blog.csdn.net/article/details/38313575

posted @   harrychinese  阅读(441)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2015-06-04 EDW on Hadoop(Hadoop上的数据仓库)技术选型和实践思考
点击右上角即可分享
微信分享提示