当前位置:编程学习 > C#/ASP.NET >>

求助:winform窗体控件多,屏幕闪的问题。

    如题,求助,情况如下:
    我的一个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秒换一批.

就好了. --------------------编程问答-------------------- Re  ZHENNIUBILE
    这是一个设备的控制系统,一百多个开关,上百个流量传感器、压力传感器等,要绘制到一起显示当前设备的状态。之前就是一个屏幕显示不完,需要滚动条才重新压缩布局显示到一个屏幕的。
    xuexiaodong2009的建议很好,但是刷新的时候没有局部之分,设备上每个监控点的状态,每秒钟都可能发生变化的。所以局部刷新可能是行不通的。
    还有问题就是,上面的线是不动的,但是每次也跟着整个屏幕重绘。用System.Drawing来画的话,线多,太难定位和布局了。也不知道显示效果如何。
--------------------编程问答-------------------- 好像以前有人問過了,當然會閃的

你試試這個控件的,用DirectX增強技術 --------------------编程问答-------------------- 有多少个开关, 就开多少个线程, 使用线程先获得各种状态数据, 如果数据跟上一个数据一样, 则不刷新.
否则,就刷新.

这样,就会减轻界面的刷新负担.
----------------------------
那个双缓冲,我感觉没啥用,呵呵 --------------------编程问答-------------------- 用选项卡分组一下吧 那个双缓冲没有什么作用! --------------------编程问答--------------------
引用 7 楼 guoja 的回复:
Re ZHENNIUBILE
  这是一个设备的控制系统,一百多个开关,上百个流量传感器、压力传感器等,要绘制到一起显示当前设备的状态。之前就是一个屏幕显示不完,需要滚动条才重新压缩布局显示到一个屏幕的。
  xuexiaodong2009的建议很好,但是刷新的时候没有局部之分,设备上每个监控点的状态,每秒钟都可能发生变化的。所以局部刷新可能是行不通的。
   还有问题就是,上面的线是不动的,但是每次也跟着整个屏幕重绘。用System.Drawing来画的话,线多,太难定位和布局了。也不知道显示效果如何。


问题是既然线是不动的,为什么也要跟着重绘呢,上千条线,这个问题解决了,可能闪屏的问题会改善很多 --------------------编程问答--------------------

this.SuspendLayout();

this.ResumeLayout(false);


把要操作的控件把在这两句代码中间, 同时考虑使用Invoke。
--------------------编程问答-------------------- 还有问题就是,上面的线是不动的,但是每次也跟着整个屏幕重绘。用System.Drawing来画的话,线多,太难定位和布局了。也不知道显示效果如何。

如果一直不动,是不是可以考虑使用图片代替线条呢?
不知道你怎么刷新的?
Invalidate(Rectangle) 
使控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向控件发送绘制消息。 (继承自 Control。)
尽量减少刷新的频率和范围 --------------------编程问答-------------------- this.SuspendLayout();
code......
this.ResumeLayout(false);
这样还是不行的。
我也想过用图片来代替上面的线条,线条虽然是不动的,但是要根据状态来改变各个线条的颜色,做成图片的话,这部分功能就不能用了。



--------------------编程问答--------------------
引用 12 楼 lovesongforever 的回复:
C# code

this.SuspendLayout();

this.ResumeLayout(false);



把要操作的控件把在这两句代码中间, 同时考虑使用Invoke。
--------------------编程问答-------------------- 还有你重绘屏幕的间隔是多长时间?如果数据正常,1秒足够了,采集的其他数据可以作为监测而不刷新,如果出现异常立即处理就行了 --------------------编程问答-------------------- C# code

this.SuspendLayout();

this.ResumeLayout(false);

把要操作的控件把在这两句代码中间, 同时考虑使用Invoke。

试过了  不行的。

还有你重绘屏幕的间隔是多长时间?如果数据正常,1秒足够了,采集的其他数据可以作为监测而不刷新,如果出现异常立即处理就行了

上面的值每秒更新一次,整个屏幕大面积的控件都要更新值或者状态。值更新后,屏幕自然就重绘了。特别是上面的线条,感觉是一部分一部分出来的。
--------------------编程问答-------------------- 会不会不是屏幕重绘的问题,而是有哪一项任务消耗CPU资源太多而影响了屏幕的重绘 --------------------编程问答-------------------- 你理一理,看哪一个模块任务比较重
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,