C# 解决窗体闪烁

在Windows窗体上造成“闪烁”的窗体上有很多控制。造成这种闪烁的原因有两个:

1.当控件需要被绘制时,Windows发送一个控件两个消息。第一个(WM_ERASEBKGND)导致背景被绘制(OnPaintBackground),第二个导致前景被绘(WM_PAINT,射击OnPaint)。首先看到背景,然后当绘图缓慢时前景变得明显。Windows窗体使用ControlStyles.OptimizedDoubleBuffer为这种闪烁提供了一个现成的解决方案。

2.有很多控件的表单需要很长时间来绘制。尤其是按钮控件的默认样式是昂贵的。一旦你得到了超过50个控件,它开始变得明显。Form类首先绘制其背景,并在控件需要去的地方留下“漏洞”。当您使用不透明度或透明度键属性时,这些孔通常是白色的,黑色的。然后每个控件都被绘制,填充在洞中。视觉效果是丑陋的,在Windows窗体中没有现成的解决方案。双缓冲不能解决它,因为它只适用于单一控制,而不是一组复合控件。

我在SDK头文件中发现了一个新的Windows风格,可用于Windows XP和(推测)Vista:WS_EX_COMPOSITED。随着窗体打开窗体,Windows XP将在窗体及其所有子控件上进行双缓冲。这有效解决了闪烁的第二个原因。这里有一个例子:

using System; 
使用System.Drawing; 
使用System.Windows.Forms;

命名空间WindowsApplication1 { 
  公共部分类Form1:窗体{ 
    公共Form1(){ 
      InitializeComponent(); 
      for(int ix = 0; ix <30; ++ ix){ 
        for(int iy = 0; iy <30; ++ iy){ 
          Button btn = new Button(); 
          btn.Location = new Point(ix * 10,iy * 10);
          this.Controls.Add(BTN); 
        } 
      } 
    } 
    protected override CreateParams CreateParams { 
      get { 
        CreateParams cp = base.CreateParams; 
        cp.ExStyle | = 0x02000000; 
        返回cp; 
      } 
    } 
  } 
}

要看到它在工作,最大限度地减少和恢复的形式,并观察其绘画行为。注释cp.ExStyle赋值以查看差异。您只需要复制并粘贴CreateParams属性即可。

一些注意事项:这不会加速绘画。绘画正在发生时,您的表单将保持不可见状态,然后在完成后弹出屏幕。而当您使用不透明度或透明度键属性时不起作用,当绘画发生时,表单轮廓将显示为丑陋的黑色矩形。最好的解决方法是使用计时器将不透明度值增加到99%,以使表单在绘制后可见。

我还没有尝试过很多,如果你有使用它的问题,请张贴到这个线程。

http://social.msdn.microsoft.com/forums/en-US/winforms/thread/aaed00ce-4bc9-424e-8c05-c30213171c2c/

解决办法很easy:

将以下代码块加在父窗体中的任意位置

protected override CreateParams CreateParams

{

get

{

CreateParams cp = base.CreateParams;

cp.ExStyle |= 0x02000000;

return cp;

}

}

原理很简单,引用以下原话:

A form that has a lot of controls takes a long time to paint.  Especially the Button control in its default style is expensive.  Once you get over 50 controls, it starts getting noticeable.  The Form class paints its background first and leaves "holes" where the controls need to go.  Those holes are usually white, black when you use the Opacity or TransparencyKey property.  Then each control gets painted, filling in the holes.  The visual effect is ugly and there's no ready solution for it in Windows Forms.  Double-buffering can't solve it as it only works for a single control, not a composite set of controls.

I discovered a new Windows style in the SDK header files, available for Windows XP and (presumably) Vista: WS_EX_COMPOSITED.  With that style turned on for your form, Windows XP does double-buffering on the form and all its child controls.

参考链接:https://social.msdn.microsoft.com/Forums/windows/en-US/aaed00ce-4bc9-424e-8c05-c30213171c2c/flickerfree-painting?forum=winforms

http://blog.csdn.net/itoccupant/article/details/32334877

C# 解决窗体闪烁的更多相关文章

  1. Delphi:解决重绘造成的窗体闪烁问题

    解决窗体闪烁问题 具体代码: 1.在声明窗体类时加入:   private     procedure CreateParams(var Params: TCreateParams); overrid ...

  2. 解决mdi窗体闪烁的问题

    /// 解决mdi窗体闪烁的问题 /// </summary> protected override CreateParams CreateParams { get { CreatePar ...

  3. 谈.Net委托与线程——解决窗体假死

    转自:http://www.cnblogs.com/smartls/archive/2011/04/08/2008981.html#2457370   引言 在之前的<创建无阻塞的异步调用> ...

  4. C# 解决窗体假死的状态

    异步调用是CLR为开发者提供的一种重要的编程手段,它也是构建高性能.可伸缩应用程序的关键.在多核CPU越来越普及的今天,异步编程允许使用非常少的线程执行很多操作.我们通常使用异步完成许多计算型.IO型 ...

  5. C# winform解决解决窗体第一次设置为最大化后,点击最大化按钮窗体无法居中问题

    public frmMain() { InitializeComponent(); //解决窗体第一次设置为最大化后,点击最大化按钮窗体无法居中问题 int x = Convert.ToInt32(( ...

  6. C# 实现PNG文件的背景透明显示,解决动态显示闪烁问题 【转】

    http://blog.sina.com.cn/s/blog_402c071e0102x4rl.html    以下内容,对于想要使用C#实现PNG图片背景透明显示,同时动态显示时无闪烁问题的人来说, ...

  7. delphi实现窗体闪烁功能

    delphi实现窗体闪烁功能 以前做窗口闪动时都没有考虑到让任务栏上的按钮闪动的问题, 现在一个客户需要任务栏按钮闪动,发现以前使用的flashwindow不能达到要求了, 查找了一下,找到flash ...

  8. 解决winform窗体闪烁问题

    如果你在Form中绘图的话,不论是不是采用的双缓存,都会看到图片在更新的时候都会不断地闪烁,解决方法就是在这个窗体的构造函数中增加以下三行代码: 请在构造函数里面底下加上如下几行: SetStyle( ...

  9. c# winform窗体闪烁解决方法

    在主窗体中任意位置加上下面的代码即可 protected override CreateParams CreateParams { get { CreateParams cp = base.Creat ...

随机推荐

  1. CentOS 7下安装pptp服务端手记 ok

    主要配置步骤 1. 安装前检查系统支持 2. 安装必要包 3. 修改相关配置文件 4. 设置开机自动启动 pptpd, iptables 5. iptables配置网络 6. 阿里云ECS可能还需要几 ...

  2. Linux(五)shell编程基础

    一.Linux shell简介 1.shell概述 Shell 是用户与内核进行交互操作的一种接口,目前最流行的 Shell 称为 bash Shell          Shell 是一门编程语言& ...

  3. hihocoder[Offer收割]编程练习赛19 D 相交的铁路线(树上路径交)

    傻逼题... 裸的树上路径交 两条树上的路径$[a,b]$和$[c,d]$有交,则有$lca(a,b)$在$[c,d]$上或$lca(c,d)$在$[a,b]$上. 其实只要深度大的$lca$在另一条 ...

  4. C# 利用mysql.data 在mysql中创建数据库及数据表

    C# 利用mysql.data 在mysql中创建数据库及数据表 using System; using System.Collections.Generic; using System.Linq; ...

  5. Java Socket UDP编程

    package com; import java.io.IOException; import java.net.*; /** * UDP Client * * Created by Administ ...

  6. 《提升c++性能的编程技术》读书笔记

    http://note.youdao.com/noteshare?id=9ab0eda264c85b774021426867e18eae

  7. 金牌架构师:我们是这样设计APP数据统计产品的

    前言:近期,智能大数据服务商“个推”推出了应用统计产品“个数”,今天我们就和大家来谈一谈个数实时统计与AI数据智能平台整合架构设计. 很多人可能好奇,拥有数百亿SDK的个推,专注消息推送服务多年,现在 ...

  8. Qt ------ 再论事件循环

    在介绍在以前,我们要认识两个术语: 可重入的(Reentrant):如果多个线程可以在同一时刻调用一个类的所有函数,并且保证每一次函数调用都引用一个唯一的数据,就称这个类是可重入的(Reentrant ...

  9. 用python + openpyxl处理excel(07+)文档 + 一些中文处理的技巧

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...

  10. tf.transpose函数解析

    tf.transpose函数解析 觉得有用的话,欢迎一起讨论相互学习~Follow Me tf.transpose(a, perm = None, name = 'transpose') 解释 将a进 ...