场景描述
在开发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类后,界面不再很明显的闪烁(加载还是有点延迟,不过不明显了)