解决Winform应用程序中窗体背景闪烁的问题
2018-01-15 21:49
302 查看
参考链接:https://my.oschina.net/Tsybius2014/blog/659742
我的操作系统是Win7,使用的VS版本是VS2012,文中的代码都是C#代码。
这几天遇到一个问题,即我用一个嵌入图片的Panel作为Winform应用程序的背景,如下图所示:
这是一个Winform窗体,里面放置了一个Panel,Dock属性为Fill,BackgroundImage使用了《少年电世界》2003年第02期的封面图片,BackgroundImageLayout使用了Stretch。
这个界面现在有两个问题:
1、在窗体第一次被打开时,背景图片会出现明显的闪烁
2、在拉动窗体的边界以调整窗体大小时,背景图片非出现明显的闪烁
为了处理这一问题,我查了一些资料,也都逐个试过了,下面先说下其中的两个有代表性方法:
方法1:直接使用双缓冲
我尝试着将这段代码加到窗体的构造函数中,并不能解决问题,闪烁依然非常明显
在MSDN上还有一篇文章《如何通过对窗体和控件使用双缓冲来减少图形闪烁》
地址:https://msdn.microsoft.com/zh-cn/library/3t7htc9c%28v=vs.80%29.aspx
这篇文章中也介绍了一个方法使用双缓冲:
这个方法依然不能解决问题。
方法2:重写CreateParams方法
方法2需要将以下这段代码放在Form类的代码内:
这个方法我一开始尝试的时候一度认为是有效的,但使用了一段时间后还是发现了问题:
1、这个方法可以解决问题1,但不能解决问题2
2、这个方法会影响一些其他控件、组件的重绘(这点才是致命的)
因此,这个方法也不能解决问题。
上面两个方法都不能解决问题,于是我继续求助度娘,终于在下面这个页面找到了解决方法:
方法3:封装Panel类
http://blog.chinaunix.net/uid-14414741-id-2814313.html
这个方法,需要新建一个PanelEnhanced类继承Panel类,代码如下:
将之前我们建立窗体中的Panel容器换为我们新封装的PanelEnhanced容器,将程序的背景图片放到里面,再运行程序,程序背景闪烁的问题就完美解决了!
END
方法4:参考其他文章(仅供参考)
我的操作系统是Win7,使用的VS版本是VS2012,文中的代码都是C#代码。
这几天遇到一个问题,即我用一个嵌入图片的Panel作为Winform应用程序的背景,如下图所示:
这是一个Winform窗体,里面放置了一个Panel,Dock属性为Fill,BackgroundImage使用了《少年电世界》2003年第02期的封面图片,BackgroundImageLayout使用了Stretch。
这个界面现在有两个问题:
1、在窗体第一次被打开时,背景图片会出现明显的闪烁
2、在拉动窗体的边界以调整窗体大小时,背景图片非出现明显的闪烁
为了处理这一问题,我查了一些资料,也都逐个试过了,下面先说下其中的两个有代表性方法:
方法1:直接使用双缓冲
SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景. SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
我尝试着将这段代码加到窗体的构造函数中,并不能解决问题,闪烁依然非常明显
在MSDN上还有一篇文章《如何通过对窗体和控件使用双缓冲来减少图形闪烁》
地址:https://msdn.microsoft.com/zh-cn/library/3t7htc9c%28v=vs.80%29.aspx
这篇文章中也介绍了一个方法使用双缓冲:
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类
http://blog.chinaunix.net/uid-14414741-id-2814313.html
这个方法,需要新建一个PanelEnhanced类继承Panel类,代码如下:
/// <summary> /// 加强版 Panel /// </summary> class PanelEnhanced : Panel { /// <summary> /// OnPaintBackground 事件 /// < b396 /span></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); } }
将之前我们建立窗体中的Panel容器换为我们新封装的PanelEnhanced容器,将程序的背景图片放到里面,再运行程序,程序背景闪烁的问题就完美解决了!
END
方法4:参考其他文章(仅供参考)
c#界面绘制的时候,底层重绘每次会清除画布背景,然后再全部重新绘制,这才是导致闪烁最主要的原因。于是重载消息发送函数操作,禁掉这条消息。代码如下: protected override void WndProc(ref Message m) { if (m.Msg == 0x0014) // 禁掉清除背景消息 return; base.WndProc(ref m); }
相关文章推荐
- 解决Winform应用程序中窗体背景闪烁的问题
- 解决Winform应用程序中窗体背景闪烁的问题
- 解决winform窗体闪烁问题
- 给MDI 父窗体添加背景和解决闪烁的问题。
- 解决winform窗体闪烁问题
- 解决Winform背景图片闪烁的问题
- 解决winform窗体闪烁问题
- 【C#】 解决winform窗体闪烁问题
- 通过设置子窗体透明度,解决C# winform 子窗体设置背景图卡的问题
- 有效解决WinForm窗体背景图片导致闪屏刷新问题
- c# 窗体的背景图片在加载时,背景图片闪烁问题 已解决
- 解决winform窗体闪烁问题
- C# winForm 窗体闪烁问题
- 解决WinForm界面闪烁问题
- winform 中用IrisSkin2 皮肤后,鼠标在窗体移动会有闪烁,GroupBox不停的闪烁 解决方法
- C# winform中不规则窗体制作的解决方案(已经解决24位色以上不能正常显示问题)
- 解决WinForm(C#)中MDI子窗体最大化的问题
- 解决Winform中弹出WPF窗体不能在文本框中输入的问题
- c#解决窗口背景贴图刷新,放大后图像闪烁问题
- C# 解决调用winform窗体顶置且解决任务栏图片显示问题