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

浙公網安備 33010602011771號