解决Winform应用程序中窗体背景闪烁的问题
本文转载: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:直接使用双缓冲
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 事件
/// </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容器,将程序的背景图片放到里面,再运行程序,程序背景闪烁的问题就完美解决了!
解决Winform应用程序中窗体背景闪烁的问题的更多相关文章
- 在WinForm应用程序中快速实现多语言的处理
在国际化环境下,越来越多的程序需要做多语言版本,以适应各种业务需求的变化.在Winform应用程序中实现多语言也有常规的处理方式处理,不过需要针对每个语言版本,重新修改Winform界面的显示,对一些 ...
- 在WinForm应用程序中快速实现多语言的处理(2)--开发框架模块的整合
我在上篇随笔<在WinForm应用程序中快速实现多语言的处理>里面介绍了Winform开发中多语言的处理解决方案,整个多语言解决方案是以实际需求为驱动,以减少代码改动,高效处理为目的,通过 ...
- C#WinForm应用程序中嵌入ECharts图表
C#WinForm应用程序中嵌入ECharts图表 程序运行效果: 下载ECharts: 官网下载ECharts :http://echarts.baidu.com/download.html 或者直 ...
- 在WinForm应用程序中嵌入WPF控件
我们知道,在WPF界面上添加WinForm的控件需要使用WindowsFormHost类.而在WinForm界面上添加WPF控件该如何做呢?有没有类似的类呢?明显是有的,ElementHost就是为了 ...
- WinForm应用程序中实现自动更新功能
WinForm应用程序中实现自动更新功能 编写人:左丘文 2015-4-20 近来在给一客户实施ECM系统,但他们使用功能并不是我们ECM制造版提供的标准功能,他们要求对系统作一些定制功能,为了避免因 ...
- 一招解决微信小程序中的H5缓存问题
一招解决微信小程序中的H5缓存问题1.问题描述开发过程中,为了更新代码方便,往往会在小程序中嵌入H5页面.但问题来了,小程序原生代码更新版本后,简单的从微信中删除或者代码强刷就可以解决缓存问题,但小程 ...
- 在WinForm应用程序中,使用选项卡控件来加载不同的Form界面!
TabPage tp=new TabPage(); your选项卡控件.Controls.Add(tp); From1 frm=new Form1(); frm.TopLevel = false; f ...
- (转)C#.NET WINFORM应用程序中控制应用程序只启动一次
原文地址 :http://www.cnblogs.com/emanlee/archive/2009/08/31/1557379.html using System; using System.Thre ...
- 解决微信小程序中Date.parse()获取时间戳IOS不兼容的问题(IOS为NaN的问题)
前端同事在做微信小程序时发现IOS获取的时间戳为空的问题,后来通过跟踪发现,原来是因为IOS系统不支持2017-01-01格式的时间导致的, var mydata = '2017-01-01 11:0 ...
随机推荐
- AndroidStudio导入Library
1.把它像Module一样导入. File >New >ImportModule(选择你要导入的Library). 如果出现了下面的情况,意思是跟项目中的Module重名,改个名字就行了. ...
- linux零基础入门总结
啊,notepad++贴过来怎么对齐格式这么糟糕呢? #root用户 $普通用户 linux命令 清屏clear翻页清屏 CRT中ctrl+L reset"清空 CRT中不起作用 ...
- glusterFS系统中文管理手册(转载)
GlusterFS系统中文管理手册 1文档说明 该文档主要内容出自 www.gluster.org 官方提供的英文系统管理手册<Gluster File System 3.3.0 A ...
- 修复 ThinkPHP3.2.3 抛出异常模块的一个BUG,关闭字段缓存功能
使用 ThinkPHP3.2.3 遇到一个奇怪的问题,正式环境上报错,提示 “页面错误!请稍后再试~” 为了查看到底出啥错误,哪里出错,于是在入口文件中加了一段代码,开启调试: defined('AP ...
- 64位操作系统 通过ODP.NET 访问ORACLE 11g
摘要:64位操作系统部署.NET 程序访问oracle时,无法连接问题.(注意:客户端是64位系统 ,服务端是否64位 还是32位无关.) 1.到oracle 官网搜索相关版本的 ODAC网址: ht ...
- python function parameter
Python 2.7.10 (default, Oct 14 2015, 16:09:02) [GCC 5.2.1 20151010] on linux2 Type "copyright&q ...
- [转]MySQL 最基本的SQL语法/语句
MySQL 最基本的SQL语法/语句,使用mysql的朋友可以参考下. DDL-数据定义语言(Create,Alter,Drop,DECLARE) DML-数据操纵语言(Select,Delete ...
- jquery向苹果或者android发送请求
var browser={ versions:function(){ var u = navigator.userAgent, app = navigator.appVersion; return { ...
- 15.django之Django-Rest-Framework
1.首先安装Django-Rest-Framework pip3 install djangorestframework pip3 install markdown Markdown为可视化 API ...
- js指定分隔符连接数组元素join()
指定分隔符连接数组元素join() join()方法用于把数组中的所有元素放入一个字符串.元素是通过指定的分隔符进行分隔的. 语法: arrayObject.join(分隔符) 参数说明: 注意:返回 ...