本人近期发现C#的控件绘制效率有些出乎意外的慢。我白思不得其解,我手动用Graphics画一个相似的控件都要快很多。这实在是有些无法解释。连续几天请教了很多朋友,学到很多东西,但是还是没能最终解释控件绘制慢的原因。所以,在此再贴一贴重申一下问题的关键,并且对之前一起讨论的朋友表示感谢,希望大家还能多多指点,继续讨论,多提出一些意见,哪怕贴出一点点猜想都好。原贴位置:http://community.csdn.net/Expert/topic/4830/4830989.xml问题大致的描述:一个窗口中添加了100多个控件(例如label),可以明显看到控件的绘制过程(控件是一个一个出现的,而不是一次性全部绘制完成并“翻页”),大约需要0.x秒绘制完成。这里首先说明几个容易被误导的问题,以此避免讨论不必要的细节:
1、应该不存在我的相关代码的效率影响。因为我的测试都是建立的新建空工程的基础上的。我用过两种方法测试:一种办法是直接在构造函数中填写最简单的生成控件的代码进行测试。另一个方法更简单,就是完全不手动写任何代码,开了新工程直接添加=>复制、粘贴=>复制、粘贴=>复制、粘贴……100多个label。
2、我所指的慢是绘制速度慢,既不是生成速度,也不是移动、滚动(因为这里不会引起整个窗口重绘,实际上只是copy贴图)。我已经发现的测试绘制速度的办法有四种:第一种是弹出时直接看速度(要求添加控件在构造期完成,否则影响测试结果);第二种是用另外一个窗口完全遮罩本窗口,然后再切换回原来的窗口;第三种是将本窗最小化/还原;第四种是将窗口大小调整到非常小,然后再拉大。还有一点要注意的就是,测试的时候窗口得稍微大点,否则看不到效果。如果你能看得清窗口中的大片控件是从某一个地方开始按顺序绘制的(大约超过0.x秒人眼就能察觉了吧),那就是我想要表达的:)

解决方案 »

  1.   

    麻烦路过的朋友都帮忙测试一下。
    最简单的办法:
      1、建立新的“windows窗口”项目。
      2、添加一个label
      3、复制、粘贴变成2个,复制、粘贴变成4个,复制、粘贴、复制、粘贴……一、二百个足矣。(最好是排规矩些哦,好看)
      4、运行。看看窗口出现时是否能看到控件绘制的延迟。
      5、最小化、还原。看看这样是不是还是延迟?不管你测试的结果是什么,请你告诉我,我希望知道延迟是不是普遍现象。以此排除工程默认选项差异、机器配置差异的影响。
      

  2.   

    先设置一个容器控件,并且可视属性为不可视,然后向容器里加入要加的控件.
    最后让容器一次性显示出来.gdi+速度慢,也没有慢到让人接受不了的程度,关键是想办做绘图缓冲.
      

  3.   

    to 问题大致的描述:一个窗口中添加了100多个控件(例如label),可以明显看到控件的绘制过程(控件是一个一个出现的,而不是一次性全部绘制完成并“翻页”),大约需要0.x秒绘制完成。use "Form.SuspendLayout" and "Form.ResumeLayout" methods
      

  4.   

    你造成这种现象的原因是,是窗体在开始的时候用SuspendLayout来停止显示,然后最后用ResumeLayout来一起显示,因此当控件比较多的时候,会造成错觉。你把这两个函数进行屏蔽,效果会好一些。
      

  5.   

    to amandag(高歌):
    真的吗?严格按照我说的方法测试?to lnwuyaowei(风可以追我):
    试过了,没有效果。说过了,效率慢不是慢在生成的时候,而是绘制。容器一次性显示出来的那一刹那,容器中的所有控件需要一个一个绘制,这是可以看得到延迟。to Knight94(愚翁):
    Form.SuspendLayout and Form.ResumeLayout 也用过了,不行。还是那句话,效率慢在绘制时,而SuspendLayout只是让控件刚生成时减少一些界面布局引起的开销。SuspendLayout、ResumeLayout并不能达到“停止”显示的的目的。
      

  6.   

    to Knight94(愚翁):
    好像我理解错了你的意思~~
    你是要我屏蔽SuspendLayout?我之前的测试是没有加SuspendLayout的,除非系统自动调用了…… 如果是自动调用的话,我就不知道应该怎么调用了。
      

  7.   

    笔误。  如果是自动调用的话,我就不知道应该怎么屏蔽了。另外,为了是效果更明显,我使用F5运行,而不是ctrl+F5。ctrl+F5也有延迟的,但是少很多。
      

  8.   

    to 你是要我屏蔽SuspendLayout?我之前的测试是没有加SuspendLayout的,除非系统自动调用了…… 如果是自动调用的话,我就不知道应该怎么调用了。在InitializeComponent函数中,系统自动加的,你把他们屏蔽了试试效果。
      

  9.   

    用Graphics画和直接用API绘制,API要比Graphics绘制快。
      

  10.   

    我前两天也碰到这个问题了,添加一大堆控件在一个容器中的时候相当慢,而且显示的时候是一个一个显示出来的,在用滚动条拖动的时候也显示出来也相当慢。
    添加时用 AddRange 速度会快一些,但也还是要好几秒
      

  11.   

    你可以试一下,在将控件添加到容器之前把容器控件的 visible 设置为 false,添加完成后再设置为 true
      

  12.   

    用BeginUP开始,绘完后再用EndUP结束,可以大大加快速度,尤其是DataGridView/ListView/ListBox等逐条添加记录时效果更明显
      

  13.   

    200 -- 300 个
    5-6秒
    在CC的管理下, 拷贝、复制不能用,需要手工chenk out res文件。
    不时在任务栏上会出现两个VS.net开发环境的图标。
    TabPage控件 会将鼠标锁在一个屏幕区域内
      

  14.   

    to Knight94(愚翁) 
    屏蔽了还是没效果:(to gatr() 
    我添加控件是在构造期的,构造期不用BeginUpdate也是不会接受视图重绘的啊to okkk(゛毒'自享受, 誰又能體會﹖)
    的确是感觉到整个窗口在编辑的时候就已经很慢了。不过你的现象比我的还恐怖
      

  15.   

    to 屏蔽了还是没效果:(我试了一下,放了将近200个button,屏蔽suspendlayout以及resumelayout,效果好多了。
      

  16.   

    不要在VS中试,你直接运行生成的.exe文件运行试试,感觉还好。