最近对代码作了一些优化,试验后效果还可以,但是发现界面会闪烁,具体是TreeView控件会闪烁,语言为C#,IDE为VS2005。在查阅一些资料,使用了一些基本技术后(如开启双缓冲),发现没什么效果。

        于是使用Profiler工具,查找出瓶颈在于每次更新完界面的EndUpdate操作(使用这个是为了减少界面更新次数,但这里不理想是因为控件中中的元素很多),猜想大概每次更新,.Net底层都会更新重绘每个图元,所以速度会慢,造成闪烁。但是如果这样,使用双缓冲应该会有较好效果。再看代码,发现可能是更新动作太过频繁,于是降低速度,有所好转,但还是不行。

       继续在网上查阅,最终找到一个方案比较合适。原来底层重绘每次会清除画布,然后再全部重新绘制,这才是导致闪烁最主要的原因。于是重载消息发送函数操作,禁掉这条消息。代码如下:

        protected override void WndProc(ref Message m)

        {

            if (m.Msg == 0x0014) // 禁掉清除背景消息

                return;

            base.WndProc(ref m);

        }

        成功!

注:双缓冲还是有用的,在更新不是很频繁且控件内含元素不是特别多的时候。一旦元素过多,每次更新时间都比较长,即便使用了双缓冲,仍解决不了闪烁问题。个人认为最终比较理想的方法还是禁掉清除背景消息。

附:一些尝试过但失败的记录

)使用setStyle

      网上有说使用setStyle函数去设置该控件的参数,具体为:

      SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);

      这三个选项参数后者是依赖前者的,必须并存,否则无效。并且这个函数本身是protected的,所以首先需要继承某控件再使用。

      这个目标是跟前面正确解决方案一致,也是禁止清除背景并开启双缓冲,但需要使用用户绘制选项,而且是全部交由用户绘制。这需要自己实现控件的全部绘制,比较麻烦。所以这个方法不是完全不可行,但是需要额外工作量,不推荐。我也没有使用。

)使用BeginUpdate和EndUpdate

      这一对操作对于需要批量操作更新控件的情景有比较好的效果,比如初始化时批量添加了大量节点。坏处就在于不能即时更新。所以,对于频繁的更新节点并希望立即反映到界面的情况不适用。如果使用并且没有禁掉清除界面消息的话,则控件看起来就会不停的闪烁,而且以白底为主,内容几乎不可见(这个视频繁程度而定)。因为界面更新都在EndUpdate处完成,操作太多导致EndUpdate阻塞时间过长,且清空在先,更新在后,导致界面看起来长时间处于空白状态。

)使用ControlStyles.EnableNotifyMessage选项

      这个选项的作用和正确解决方案也是一致的。使用方法是:

      SetStyle(ControlStyles.EnableNotifyMessage, true);

      protected override void onNotifyMessage(Message m)

      {

               // 此处书写过滤消息代码

      }

      但是实际实验显示无效果,不知是什么原因,没有细究。

原文:http://www.cnblogs.com/peteryj/archive/2011/04/25/2027208.html

C#控件的闪烁问题解决方法总结的更多相关文章

  1. 第三方分页控件aspnetPager出现问题解决方法

    问题描述: 今天在打开以前的项目使用vs2013打开后并且生成解决方案的时候发现报错了.经过检查发现是由于第三方分页控件aspnetPager在页面上不能引用到了. 解决方法: 1. 首先将AspNe ...

  2. IE6下div层被select控件遮住的问题解决方法

    Select在IE6下是处于最顶层的,因此想要遮住它,设置zIndex属性是不行的,就需要一个优先级更高的元素,就是iframe,当把iframe嵌套在弹出div层中后,把iframe设置为不可见,但 ...

  3. WPF中不规则窗体与WebBrowser控件的兼容问题解决办法

    原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...

  4. C# winfrom界面跳转闪烁问题解决方法

    在窗体的构造函数中添加代码: SetStyle(ControlStyles.UserPaint, true); SetStyle(ControlStyles.AllPaintingInWmPaint, ...

  5. C#常用控件的属性以及方法(转载)

    -----以前看别人的,保存了下来,但是忘了源处,望见谅. C#常用控件属性及方法介绍 目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox(文本框)控件 4.RichText ...

  6. [转] WinForm实现移除控件某个事件的方法

    原文 WinForm实现移除控件某个事件的方法 本文实例讲述了WinForm实现移除控件某个事件的方法,供大家参考借鉴一下.具体功能代码如下: 主要功能部分代码如下: /// <summary& ...

  7. MFC控件编程之 按钮编辑框.静态文本的使用,以及访问控件的七种方法.

    MFC控件编程之 按钮编辑框.静态文本的使用以及访问控件的七种方法. 一丶按钮.静态文本的通用属性. 他们都有一个属性.就是可以输入标题内容.以及可以自定义控件ID. 创建一个MFC Dlg对话框. ...

  8. WPF编程,通过Double Animation动态旋转控件的一种方法。

    原文:WPF编程,通过Double Animation动态旋转控件的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/art ...

  9. WPF编程,通过Double Animation同时动态缩放和旋转控件的一种方法。

    原文:WPF编程,通过Double Animation同时动态缩放和旋转控件的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_4330793 ...

随机推荐

  1. 笔记:Python实现二分查找

    def search(sequence, number, lower=0, upper=None): if upper is None: upper = len(sequence) - 1 if lo ...

  2. CF 540D Bad Luck Island

    一看就是DP题(很水的一道紫题) 设\(dp[i][j][k]\)为留下\(i\)个\(r\)族的人,死去\(j\)个\(s\)族的人,死去\(k\)个\(p\)族的人的概率(跟其他的题解有点差别,但 ...

  3. leetcode-227-基本计算器②

    题目描述: 方法一:中缀转后缀 #!_*_coding:utf-8_*_ class Solution: def calculate(self, s: str) -> int: def in_t ...

  4. Python短信电话报警

    sid 和token 需要自己去https://www.twilio.com/try-twilio注册twilio 账号申请是免费的  from后面的电话也是官方提供的 直接看脚本 # -*-cond ...

  5. curl 基础

    简介 curl 是常用的命令行工具,用来请求 Web 服务器.它的名字就是客户端(client)的 URL 工具的意思. 它的功能非常强大,命令行参数多达几十种.如果熟练的话,完全可以取代 Postm ...

  6. thinkphp 前置和后置操作

    前置和后置操作指的是在执行某个操作方法之前和之后会自动调用的方法,不过仅对访问控制器有效. 其他的分层控制器层和内部调用控制器的情况下前置和后置操作是无效的. 系统会检测当前操作是否具有前置和后置操作 ...

  7. C++——虚继承(不要使用,会导致二义性)

    如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性 总结: 如果一个派生类从多个基类派生,而这些基类又有一个共同 的基类,则在对该基类中声明 ...

  8. C++——类的多继承

    多继承概念 一个类有多个直接基类的继承关系称为多继承 多继承声明语法 class  派生类名 : 访问控制  基类名1 ,  访问控制  基类名2 ,  … , 访问控制  基类名n { 数据成员和成 ...

  9. CF459E Pashmak and Graph (Dag dp)

    传送门 解题思路 \(dag\)上\(dp\),首先要按照边权排序,然后图都不用建直接\(dp\)就行了.注意边权相等的要一起处理,具体来讲就是要开一个辅助数组\(g[i]\),来避免同层转移. 代码 ...

  10. HttpServletRequest的方法详细说明

    1.Java 部分request.getHeader()详细说明 == JAVA 部分request.getHeader() 详细说明== System.out.println("rotoc ...