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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2015-06-04 EDW on Hadoop(Hadoop上的数据仓库)技术选型和实践思考