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. 【BZOJ4455】小星星(动态规划,容斥)

    [BZOJ4455]小星星(动态规划,容斥) 题面 BZOJ 洛谷 Uoj 题解 题意说简单点就是给定一张\(n\)个点的图和一棵\(n\)个点的树,现在要让图和树之间的点一一对应,并且如果树上存在一 ...

  2. 日志分割工具——cronolog

    使用cronolog可以格式化日志文件的格式,比如按时间分割,易于管理和分析. 1.下载软件 http://cronolog.org/download/index.html 用法见 lighttpd配 ...

  3. 《剑指offer》— JavaScript(9)变态跳台阶

    变态跳台阶 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级--它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 实现代码 function jumpFloor(number) { ...

  4. Educational Codeforces Round 24 A 水 B stl C 暴力 D stl模拟 E 二分

    A. Diplomas and Certificates time limit per test 1 second memory limit per test 256 megabytes input ...

  5. Java Socket TCP编程

    package com; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * Socket Se ...

  6. windows使用composer.phar

    把composer.phar复制到php安装目录下, 新建一个composer.bat文件,编辑 @php "%~dp0composer.phar" %* 保存,然后就可以使用co ...

  7. 新式类 VS 经典类

    一.概述 Python中支持多继承,也就是一个子类可以继承多个父类/基类.当一个调用一个自身没有定义的属性时,它是按照何种顺序去父类中寻找的呢?尤其是当众多父类中都包含有同名的属性,这就涉及到新式类 ...

  8. webpack中Module build failed: Unknown word (2:1)

    在新建的webpack.config.js文件中配置好style-loader和css-loader,注意顺序为:style-loader,css-loader,less-loader,postcss ...

  9. Error : getaddrinfo ENOTFOUND registry.npmjs.org registry.npmjs.org:443

    环境 阿里云 centos7 node v8.11.3 npm 5.6.0 错误 npm update 解决 ping registry.npmjs.org 发现https://registry.np ...

  10. (转)使用Excel批量给数据添加单引号和逗号

    在使用PLSQL连接oracle数据库处理数据的过程中,常用的操作是通过ID查询出数据,ID需要附上单引号,如果查询的ID为一条或者几条,我们手动添加即可,但是如果是几百条.几千条的话,就需要使用一些 ...