我的操作系统是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容器,将程序的背景图片放到里面,再运行程序,程序背景闪烁的问题就完美解决了!