panel设置背景透明后,窗体大小改变时,界面闪烁

场景描述

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章