在FlowLayoutPanel滚动期间,背景扭曲+闪烁
我有一个具有背景的Windows窗体应用程序。 在其中,我有一个透明背景的flowlayoutpanel。 滚动时,会发生以下情况:
我也看到一些闪烁。 我已经尝试了所有双缓冲业务,但它不起作用。
有什么建议?
是的,这不起作用。 这是一个有所改进的类:
using System; using System.Windows.Forms; class MyFlowLayoutPanel : FlowLayoutPanel { public MyFlowLayoutPanel() { this.DoubleBuffered = true; } protected override void OnScroll(ScrollEventArgs se) { this.Invalidate(); base.OnScroll(se); } }
编译并将其从工具箱顶部拖放到表单上。 然而,它无法解决根本问题,“拖动时显示窗口内容”选项。 这是一个系统选项,它将为更高版本的Windows打开。 当它打开时,Windows本身会滚动面板的内容,然后要求应用程序绘制滚动显示的部分。 OnScroll方法会覆盖该方法,确保重新绘制整个窗口以保持背景图像的位置。 最终结果不是很好,你会看到图像在做“pogo”,在滚动时上下跳跃。
唯一的解决方法是关闭系统选项。 这不是一个实际的修复,用户喜欢这个选项,它会影响每个程序,而不仅仅是你的程序。 如果你不能与pogo一起生活,那么你将不得不放弃透明度。
这对我有用。
public class CustomFlowLayoutPanel : FlowLayoutPanel { public CustomFlowLayoutPanel() : base() { this.SetStyle(ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); } protected override void OnScroll(ScrollEventArgs se) { this.Invalidate(); base.OnScroll(se); } protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // WS_CLIPCHILDREN return cp; } } }
我很高兴地报告说,Hans和整个互联网(只是学习WPF …… pfffft)在这里是错误的。
问题出在WM_HSCROLL和WM_VSCROLL事件中。 通过一些试验和错误,我发现,如果我足够快地拖动滚动条,我能够将背景的鬼副本移动到实际背景上,这背景是我想要的。 因此,无论在可滚动控件内发生什么,Windows 都能够跟上并且一些不同步的重绘是导致剪切的原因。
那么你如何解决这个问题呢?
-
将可滚动控件设置为DoubleBuffered。
-
捕获WM_HSCROLL / WM_VSCROLL消息。 无效。 将“do_not_paint”标志设置为true。 调用base.WndProc()。 将“do_not_paint”标志设置为false。 更新。
-
捕获WM_PAINT和相关消息。 如果“do_not_paint”标志为false,则仅调用base.WndProc()。
这样做是允许可滚动控件执行它需要做的任何布局计算和滚动条重新定位,但不允许它重绘任何会触发剪切效果的内容。
我将Application.DoEvents()添加到FlowPanel amd的Scroll事件中,该事件停止了我得到的FlowPanel子控件的模糊。
这有点晚了……但如果你搞乱了Color.Transparent,就会发生这种情况。 检查FlowLayoutPanel是否具有透明背景。 如果是这样,请尝试改变它。