解决C# Winform应用程序中窗体背景闪烁的问题

我的操作系统是Win7,使用的VS版本是VS2010,文中的代码都是C#代码。

一直觉得C#winform不好看,想美化一下,但是碰到的问题好多多。
1.开始使用IrisSkin4控件,界面好看了一点,刚开始运行的时候,界面闪烁很厉害、很慢,而且Microsoft.VisualBasic.PowerPacks.OvalShape控件显示不稳定,开始可以看到一下子就看不到了,还没找到很好的解决办法。
2.后面想到用好看点的图片做背景图片,将FormBordStyle设置为None,把按钮设置成popup形式(直接用图片里面的背景做按钮背景),但是即使开启了双缓存还是闪烁很厉害。

3.继续百度,用一个嵌入图片的Panel作为Winform应用程序的背景,在Winform窗体里面将FormBordStyle设置为None,放置了一个Panel,Dock属性为Fill(大小跟窗体大小一样),BackgroundImage放入图片,BackgroundImageLayout使用了Stretch。

这个界面现在有两个问题:
1、在窗体第一次被打开时,背景图片会出现明显的闪烁
2、在编程界面里面,设计窗体大小、放置控件时,窗体出现明显的闪烁

为了处理这一问题,我查了一些资料,也都逐个试过了,下面先说下其中的两个有代表性方法:

方法1:直接使用双缓冲

    SetStyle(ControlStyles.UserPaint, true);
    SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
    SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲

我尝试着将这段代码加到窗体的构造函数中,并不能解决问题,闪烁依然非常明显

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

这个方法依然不能解决问题。

方法2:重写CreateParams方法

方法2需要将以下这段代码放在Form类的代码内:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams paras = base.CreateParams;
        paras.ExStyle |= 0x02000000;
        return paras;
    }
}

这个方法我一开始尝试的时候认为是有效的,但是:

1、这个方法可以解决问题1,但不能解决问题2

2、这个方法会影响一些其他控件、组件的重绘(这点才是致命的)

因此,这个方法也不能解决问题。

方法3:封装Panel类

这个方法,需要新建一个PanelEnhanced类继承Panel类,代码如下:

/// <summary>
/// 加强版 Panel
/// </summary>
class PanelEnhanced : Panel
{
    /// <summary>
    /// OnPaintBackground 事件
    /// </summary>
    /// <param name="e"></param>
    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);
    }
}

引用新的PanelEnhanced控件类
在form.Designer.cs文件里面的InitializeComponent() 中,替换以下代码:

//this.panel1 = new System.Windows.Forms.Panel();
this.panel1=new PanelEnhanced();

将之前我们建立窗体中的Panel容器换为我们新封装的PanelEnhanced容器,将程序的背景图片放到里面,再运行程序,程序背景闪烁的问题就完美解决了!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值