问题描述
如题,求助,情况如下:我的一个winform窗体,用于监控设备的实时状态。上面有比较多的线,上千条,label四百个左右,用于实时显示各个监控点的状态。现在的问题是,当切换窗体或者label值变化的时候,可能是窗体重绘,整个屏幕就会闪,严重影响性能。用了双缓冲,没有一点用。this.SetStyle(ControlStyles.UserPaint,true);this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);//禁止擦除背景.this.SetStyle(ControlStyles.DoubleBuffer,true);//双缓冲this.UpdateStyles();不知道各位大虾遇到此类情况是如何解决的,跪求。
解决方案
解决方案二:
用DirectX或者System.Drawing来画。。不要堆砌控件。
解决方案三:
控件太多卡是正常的,400多个能同时在一个页面里显示么?如果不能可以想办法每次只绘制显示区域内的控件,其余的不显示
解决方案四:
dodducs整个图本来是1.5*1.5个屏幕绘制好的,原来只是切换页面的时候稍微有点闪,感官上没什么影响。但考虑原来情况不能一下看完整的状态,需要拖动滚动条,所以就重新布局到一个屏幕以内,结果就闪的相当明显了。CGabriel的建议很好,但是上面有上千条直线,如果用System.Drawing来画,太难定位和布局了。
解决方案五:
使用局部刷新技术,只刷新需要的部分
解决方案六:
这种情况很正常,我做ERP的界面的时候也会有同样情况。能不能用集合存储窗体,再根据情况来取值。
解决方案七:
重新设计,监控100个探头,也没必要把100个屏幕都显示在一个界面上吧.象地铁那样,只显示4个,5秒换一批.就好了.
解决方案八:
ReZHENNIUBILE这是一个设备的控制系统,一百多个开关,上百个流量传感器、压力传感器等,要绘制到一起显示当前设备的状态。之前就是一个屏幕显示不完,需要滚动条才重新压缩布局显示到一个屏幕的。xuexiaodong2009的建议很好,但是刷新的时候没有局部之分,设备上每个监控点的状态,每秒钟都可能发生变化的。所以局部刷新可能是行不通的。还有问题就是,上面的线是不动的,但是每次也跟着整个屏幕重绘。用System.Drawing来画的话,线多,太难定位和布局了。也不知道显示效果如何。
解决方案九:
好像以前有人問過了,當然會閃的,用DirectX增強技術
解决方案十:
有多少个开关,就开多少个线程,使用线程先获得各种状态数据,如果数据跟上一个数据一样,则不刷新.否则,就刷新.这样,就会减轻界面的刷新负担.----------------------------那个双缓冲,我感觉没啥用,呵呵
解决方案十一:
用选项卡分组一下吧那个双缓冲没有什么作用!
解决方案十二:
引用7楼guoja的回复:
ReZHENNIUBILE这是一个设备的控制系统,一百多个开关,上百个流量传感器、压力传感器等,要绘制到一起显示当前设备的状态。之前就是一个屏幕显示不完,需要滚动条才重新压缩布局显示到一个屏幕的。xuexiaodong2009的建议很好,但是刷新的时候没有局部之分,设备上每个监控点的状态,每秒钟都可能发生变化的。所以局部刷新可能是行不通的。还有问题就是,上面的线是不动的,但是每次也跟着整个屏幕重绘。用System.Drawing来画的话,线多,太难定位和布局了。也不知道显示效果如何。
问题是既然线是不动的,为什么也要跟着重绘呢,上千条线,这个问题解决了,可能闪屏的问题会改善很多
解决方案十三:
this.SuspendLayout();this.ResumeLayout(false);
把要操作的控件把在这两句代码中间,同时考虑使用Invoke。
解决方案十四:
还有问题就是,上面的线是不动的,但是每次也跟着整个屏幕重绘。用System.Drawing来画的话,线多,太难定位和布局了。也不知道显示效果如何。如果一直不动,是不是可以考虑使用图片代替线条呢?不知道你怎么刷新的?Invalidate(Rectangle)使控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向控件发送绘制消息。(继承自Control。)尽量减少刷新的频率和范围
解决方案十五:
this.SuspendLayout();code......this.ResumeLayout(false);这样还是不行的。我也想过用图片来代替上面的线条,线条虽然是不动的,但是要根据状态来改变各个线条的颜色,做成图片的话,这部分功能就不能用了。
解决方案:
引用12楼lovesongforever的回复:
C#codethis.SuspendLayout();this.ResumeLayout(false);把要操作的控件把在这两句代码中间,同时考虑使用Invoke。
解决方案:
还有你重绘屏幕的间隔是多长时间?如果数据正常,1秒足够了,采集的其他数据可以作为监测而不刷新,如果出现异常立即处理就行了
解决方案:
C#codethis.SuspendLayout();this.ResumeLayout(false);把要操作的控件把在这两句代码中间,同时考虑使用Invoke。试过了不行的。还有你重绘屏幕的间隔是多长时间?如果数据正常,1秒足够了,采集的其他数据可以作为监测而不刷新,如果出现异常立即处理就行了上面的值每秒更新一次,整个屏幕大面积的控件都要更新值或者状态。值更新后,屏幕自然就重绘了。特别是上面的线条,感觉是一部分一部分出来的。
解决方案:
会不会不是屏幕重绘的问题,而是有哪一项任务消耗CPU资源太多而影响了屏幕的重绘
解决方案:
你理一理,看哪一个模块任务比较重