場景描述
在開發winform程序時,主窗體設置了背景圖片,然後設置各自定義控件backColor=Transparent,以及自定義控件內的各panel的backColor=Transparent。
問題:加載時,各panel區域閃爍1~2秒左右
解決方案
1、不適合此場景的方案
1.1、重寫CreateParams
/// <summary>
/// 解決加載閃爍,背景透明等問題
/// </summary>
protected override CreateParams CreateParams
{
get
{
var parms = base.CreateParams;
parms.Style &= ~0x02000000;
return parms;
}
}
結果:無效
1.2、重寫panel - 設置禁止擦除背景、雙緩衝
/// <summary>
/// 用途:防止Panel閃爍
/// </summary>
public partial class NewPanel : Panel
{
public NewPanel()
{
InitializeComponent();
this.DoubleBuffered = true;//設置本窗體
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
SetStyle(ControlStyles.DoubleBuffer, true); // 雙緩衝
}
public NewPanel(IContainer container)
{
container.Add(this);
InitializeComponent();
this.DoubleBuffered = true;//設置本窗體
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
SetStyle(ControlStyles.DoubleBuffer, true); // 雙緩衝
}
}
結果:無效
1.3、封裝Panel類 - 使用雙緩衝和背景重繪
class PanelEnhanced : Panel
{
///
/// OnPaintBackground 事件
///
///
protected override void OnPaintBackground(PaintEventArgs e)
{
// 重載基類的背景擦除函數,
// 解決窗口刷新,放大,圖像閃爍
return;
}
/// <summary>
/// OnPaint 事件
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
// 使用雙緩衝
this.DoubleBuffered = true;
// 背景重繪移動到此
if (this.BackgroundImage != null)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
e.Graphics.DrawImage(
this.BackgroundImage,
new System.Drawing.Rectangle(0, 0, this.Width, this.Height),
0,
0,
this.BackgroundImage.Width,
this.BackgroundImage.Height,
System.Drawing.GraphicsUnit.Pixel);
}
base.OnPaint(e);
}
}
結果:加載時不閃爍,但是更改窗體大小時(最大化、最小化、拖動)panel背景色變爲黑色。可能是因爲背景重繪導致的吧。沒細研究,這個方法應該不適合我的情況,開始繼續找方案。
2、適合的方案
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Test
{
//開啓雙緩衝
class MyPanel:Panel
{
public MyPanel()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true);
}
}
}
結果:替換窗體中的panel類後,界面不再很明顯的閃爍(加載還是有點延遲,不過不明顯了)