当前位置: 代码迷 >> C# >> winform控件太多,如跟解决拖动窗口大小时的闪烁与卡顿现象
  详细解决方案

winform控件太多,如跟解决拖动窗口大小时的闪烁与卡顿现象

热度:83   发布时间:2016-05-05 04:44:36.0
winform控件太多,如和解决拖动窗口大小时的闪烁与卡顿现象
我现在需要做一个仿真硬件界面,需要模拟硬件按钮,所以使用了很多button(30来个),但是上级的要求是这个界面可以随便拖动窗口边框放大缩小,因此我在sizechanged里面写了button随着窗口大小的改变自适应自己的位置和大小,所以问题就来了,拉伸窗口大小的时候button一直闪烁而且拉伸很不流畅,我试了在程序构造函数那块使用了双缓冲而且在添加button前后使用了suspendlayout和resumelayout,但是都没有达到我想要的效果,是不是我应该在sizechanged()里面还该做什么
------解决思路----------------------
默认地,放上30个Button并不或者这样。

看看你有没有什么“轮询杀手”代码,例如自己写什么Paint、什么定时器,都是很容易被初学者滥用的。

你可以在每一个自定义方法内第一行写上类似
Debug.Print("------>private void map_SpiritLoaded({0}, {1})", x, y);

这样的代码。然后当你“用鼠标拖动窗口边框”3秒钟,看看在调试“输出”窗口里打印的程序轨迹,看看哪些方法被疯狂调用。
------解决思路----------------------
可以使用Anchor属性来实现自适应,效果也许会比你自己在SizeChanged事件里去控制好些。
------解决思路----------------------
看样子问题是集中到了你编写的画图函数了。
一个方法就是不直接画到窗体上,而是画在内存中的图片上,然后把图片显示到窗体上。让重绘的处理很消耗资源的时候还可以建立一个新线程去画那个内存图片。
------解决思路----------------------
设置双缓冲不行 锁定窗口刷新
------解决思路----------------------
引用:
Quote: 引用:

使用Anchor属性,方便有简单。

Anchor设置为Top,就表示控件与父容器的上面距离保持不变。
Anchor设置为Top, Right,就表示控件与父容器的上面和右边的距离保持不变。
以此类推。

可以得到一个很方便的,拉伸效果。

现在的问题是拖动过程中卡顿闪烁
你自己sizechange里去修改top/left/width/height和用anchor是不一样的。你在resize里写,ui被频繁重绘,这是你闪烁的原因。你换成anchor,效果会好很多。你也可以采纳15楼的建议,总之,就是尽可能减少ui重绘。
------解决思路----------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

使用Anchor属性,方便有简单。

Anchor设置为Top,就表示控件与父容器的上面距离保持不变。
Anchor设置为Top, Right,就表示控件与父容器的上面和右边的距离保持不变。
以此类推。

可以得到一个很方便的,拉伸效果。

现在的问题是拖动过程中卡顿闪烁
你自己sizechange里去修改top/left/width/height和用anchor是不一样的。你在resize里写,ui被频繁重绘,这是你闪烁的原因。你换成anchor,效果会好很多。你也可以采纳15楼的建议,总之,就是尽可能减少ui重绘。

我要做的是控件随着窗口大小的改变自动调节它自己的位置和大小,anchor好像实现不了吧,他只是设置按钮距离窗口边缘位置不变,重写layout只保存我画的那部分吗?
设置控件到父对象边框之间的距离,如果只制定top、left就可以让他们保持在左上角。相反bottom和right就可以让他们在右下角,相应的全部指定可以随窗口变大缩小。当然无法满足所有情况,但绝大多数情况下足够用了,你的那么多按钮如果大多数都用系统方法重新摆放位置和大小,少数几个才去手工处理,那么效率也会高不少。

不一定重写layout,假设你在resize事件里加上一个标志位,你在mouse button up事件里检查这个标志位,如果为true那么就重新计算按钮位置和大小,那么整个resize过程中只有最后鼠标释放的时候才重绘,而不是在resize过程中多次重绘。
------解决思路----------------------
 先禁用重绘
在启用重绘

设置双缓冲也
不是太管用的

const int WM_SETREDRAW = 0xB;
SendMessage(base.Handle, WM_SETREDRAW, 1, 0); // 禁用
SendMessage(base.Handle, WM_SETREDRAW, 1, 0); // 启用
------解决思路----------------------
 protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle 
------解决思路----------------------
= 0x02000000;////用双缓冲绘制窗口的所有子控件
                return cp;
            }
        }
  相关解决方案