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

qq_16600121 2014-11-15 03:01:14
我现在需要做一个仿真硬件界面,需要模拟硬件按钮,所以使用了很多button(30来个),但是上级的要求是这个界面可以随便拖动窗口边框放大缩小,因此我在sizechanged里面写了button随着窗口大小的改变自适应自己的位置和大小,所以问题就来了,拉伸窗口大小的时候button一直闪烁而且拉伸很不流畅,我试了在程序构造函数那块使用了双缓冲而且在添加button前后使用了suspendlayout和resumelayout,但是都没有达到我想要的效果,是不是我应该在sizechanged()里面还该做什么
...全文
3086 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
llx1990 2015-03-01
  • 打赏
  • 举报
回复 2
不用试了,不管加什么双缓冲那都骗人的,最多减轻一点,不管怎么样都是会闪烁的,这个是winform设计的问题。 最有效的办法是使用directUI脏句柄重绘控件,可以达到原生c++的绘图效率。 P.S我很讨厌2L那装X的样子。明明懂的皮毛一样的却到处装大神。
泡泡龙 2014-11-30
  • 打赏
  • 举报
回复
http://www.cnblogs.com/Charltsing/p/WinFormNoFlicker.html
puler 2014-11-30
  • 打赏
  • 举报
回复
引用 24 楼 Windowsvipcuvs 的回复:
先禁用重绘 在启用重绘 设置双缓冲也 不是太管用的 const int WM_SETREDRAW = 0xB; SendMessage(base.Handle, WM_SETREDRAW, 1, 0); // 禁用 SendMessage(base.Handle, WM_SETREDRAW, 1, 0); // 启用
感觉可行
eldersubhuti 2014-11-30
  • 打赏
  • 举报
回复
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;////用双缓冲绘制窗口的所有子控件
return cp;
}
}
相思梦 2014-11-29
  • 打赏
  • 举报
回复
先禁用重绘 在启用重绘 设置双缓冲也 不是太管用的 const int WM_SETREDRAW = 0xB; SendMessage(base.Handle, WM_SETREDRAW, 1, 0); // 禁用 SendMessage(base.Handle, WM_SETREDRAW, 1, 0); // 启用
wjq 2014-11-28
  • 打赏
  • 举报
回复
引用 21 楼 qq_16600121 的回复:
[quote=引用 20 楼 wjq 的回复:] [quote=引用 19 楼 qq_16600121 的回复:] [quote=引用 16 楼 xiongdan1982 的回复:] 使用Anchor属性,方便有简单。 Anchor设置为Top,就表示控件与父容器的上面距离保持不变。 Anchor设置为Top, Right,就表示控件与父容器的上面和右边的距离保持不变。 以此类推。 可以得到一个很方便的,拉伸效果。
现在的问题是拖动过程中卡顿闪烁[/quote]你自己sizechange里去修改top/left/width/height和用anchor是不一样的。你在resize里写,ui被频繁重绘,这是你闪烁的原因。你换成anchor,效果会好很多。你也可以采纳15楼的建议,总之,就是尽可能减少ui重绘。[/quote] 我要做的是控件随着窗口大小的改变自动调节它自己的位置和大小,anchor好像实现不了吧,他只是设置按钮距离窗口边缘位置不变,重写layout只保存我画的那部分吗?[/quote]设置控件到父对象边框之间的距离,如果只制定top、left就可以让他们保持在左上角。相反bottom和right就可以让他们在右下角,相应的全部指定可以随窗口变大缩小。当然无法满足所有情况,但绝大多数情况下足够用了,你的那么多按钮如果大多数都用系统方法重新摆放位置和大小,少数几个才去手工处理,那么效率也会高不少。 不一定重写layout,假设你在resize事件里加上一个标志位,你在mouse button up事件里检查这个标志位,如果为true那么就重新计算按钮位置和大小,那么整个resize过程中只有最后鼠标释放的时候才重绘,而不是在resize过程中多次重绘。
kxyzjm62 2014-11-28
  • 打赏
  • 举报
回复
向大家学习学习
qq_16600121 2014-11-20
  • 打赏
  • 举报
回复
引用 20 楼 wjq 的回复:
[quote=引用 19 楼 qq_16600121 的回复:] [quote=引用 16 楼 xiongdan1982 的回复:] 使用Anchor属性,方便有简单。 Anchor设置为Top,就表示控件与父容器的上面距离保持不变。 Anchor设置为Top, Right,就表示控件与父容器的上面和右边的距离保持不变。 以此类推。 可以得到一个很方便的,拉伸效果。
现在的问题是拖动过程中卡顿闪烁[/quote]你自己sizechange里去修改top/left/width/height和用anchor是不一样的。你在resize里写,ui被频繁重绘,这是你闪烁的原因。你换成anchor,效果会好很多。你也可以采纳15楼的建议,总之,就是尽可能减少ui重绘。[/quote] 我要做的是控件随着窗口大小的改变自动调节它自己的位置和大小,anchor好像实现不了吧,他只是设置按钮距离窗口边缘位置不变,重写layout只保存我画的那部分吗?
Jay_pbsh 2014-11-19
  • 打赏
  • 举报
回复
静待解决方案
於黾 2014-11-19
  • 打赏
  • 举报
回复
引用 5 楼 qq_16600121 的回复:
[quote=引用 4 楼 Z65443344 的回复:] 也许你可以考虑一下在鼠标放开的时候重绘,而不是在拉动过程中不断的重绘
那就是跟ResizeEnd一样了?[/quote] 其实也可以动态开个timer,在拖动过程中定时重绘,当ResizeEnd的时候就把它关掉 这样总不至于即使鼠标移动了1个像素,也要重绘一次
wjq 2014-11-19
  • 打赏
  • 举报
回复
引用 19 楼 qq_16600121 的回复:
[quote=引用 16 楼 xiongdan1982 的回复:] 使用Anchor属性,方便有简单。 Anchor设置为Top,就表示控件与父容器的上面距离保持不变。 Anchor设置为Top, Right,就表示控件与父容器的上面和右边的距离保持不变。 以此类推。 可以得到一个很方便的,拉伸效果。
现在的问题是拖动过程中卡顿闪烁[/quote]你自己sizechange里去修改top/left/width/height和用anchor是不一样的。你在resize里写,ui被频繁重绘,这是你闪烁的原因。你换成anchor,效果会好很多。你也可以采纳15楼的建议,总之,就是尽可能减少ui重绘。
卧_槽 2014-11-19
  • 打赏
  • 举报
回复
先把重绘全去掉。
effun 2014-11-19
  • 打赏
  • 举报
回复
可以使用Anchor属性来实现自适应,效果也许会比你自己在SizeChanged事件里去控制好些。
qq_16600121 2014-11-19
  • 打赏
  • 举报
回复
引用 6 楼 devmiao 的回复:
其实就不应该用按钮,一个按钮相当于一个窗口,你看扫雷,要用按钮做,那得多大的开销。
那您有什么更好的建议吗,求指教
qq_16600121 2014-11-19
  • 打赏
  • 举报
回复
引用 16 楼 xiongdan1982 的回复:
使用Anchor属性,方便有简单。 Anchor设置为Top,就表示控件与父容器的上面距离保持不变。 Anchor设置为Top, Right,就表示控件与父容器的上面和右边的距离保持不变。 以此类推。 可以得到一个很方便的,拉伸效果。
现在的问题是拖动过程中卡顿闪烁
qq_16600121 2014-11-19
  • 打赏
  • 举报
回复
引用 14 楼 geyewei 的回复:
看样子问题是集中到了你编写的画图函数了。 一个方法就是不直接画到窗体上,而是画在内存中的图片上,然后把图片显示到窗体上。让重绘的处理很消耗资源的时候还可以建立一个新线程去画那个内存图片。
那就是双缓冲呗
相思梦 2014-11-19
  • 打赏
  • 举报
回复
设置双缓冲不行 锁定窗口刷新
xiongdan1982 2014-11-19
  • 打赏
  • 举报
回复
使用Anchor属性,方便有简单。 Anchor设置为Top,就表示控件与父容器的上面距离保持不变。 Anchor设置为Top, Right,就表示控件与父容器的上面和右边的距离保持不变。 以此类推。 可以得到一个很方便的,拉伸效果。
phommy 2014-11-19
  • 打赏
  • 举报
回复
引用 2 楼 qq_16600121 的回复:
[quote=引用 1 楼 sp1234 的回复:] 默认地,放上30个Button并不或者这样。 看看你有没有什么“轮询杀手”代码,例如自己写什么Paint、什么定时器,都是很容易被初学者滥用的。 你可以在每一个自定义方法内第一行写上类似
Debug.Print("------>private void map_SpiritLoaded({0}, {1})", x, y);
这样的代码。然后当你“用鼠标拖动窗口边框”3秒钟,看看在调试“输出”窗口里打印的程序轨迹,看看哪些方法被疯狂调用。
的确,我的代码里面不止定义了窗口paint函数,还有其他一些画图函数,每拉动一次窗口就得重绘,请教一下,这个有没有什么好的解决方法[/quote] 那看来你需要判断当前控件是否SuspendLayout决定是否要做你自己重绘了(讨厌的是这个状态只能反射拿到)。具体点,在重写的OnLayoutSuspended里把你绘制好的保存一下,在拖动期间直接帖你保存的这个图,当OnLayoutResuming时再重绘
geyewei 2014-11-19
  • 打赏
  • 举报
回复
看样子问题是集中到了你编写的画图函数了。 一个方法就是不直接画到窗体上,而是画在内存中的图片上,然后把图片显示到窗体上。让重绘的处理很消耗资源的时候还可以建立一个新线程去画那个内存图片。
加载更多回复(8)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧