我有一个具有背景的 Windows 窗体应用程序。在其中,我有一个带有透明背景的 flowlayoutpanel。当我滚动时,会发生以下情况:
我也看到一些闪烁。我已经尝试了所有的双缓冲业务,但它不起作用。
有什么建议么?
我有一个具有背景的 Windows 窗体应用程序。在其中,我有一个带有透明背景的 flowlayoutpanel。当我滚动时,会发生以下情况:
我也看到一些闪烁。我已经尝试了所有的双缓冲业务,但它不起作用。
有什么建议么?
这对我有用。
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;
}
}
}
是的,这行不通。这是一个稍微改进它的类:
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,那么您将不得不放弃透明度。
我很高兴地报告说,汉斯和整个互联网(只要学习 WPF....pfffft)在这里是错误的。
问题出在 WM_HSCROLL 和 WM_VSCROLL 事件中。通过一些尝试和错误,我发现,如果我拖动滚动条的速度足够快,我能够将我的背景的幻影副本移动到实际背景上,而实际背景是我想要的。因此,无论可滚动控件内部发生什么,Windows都能跟上,一些不同步的重绘是导致剪切的原因。
那么你如何解决这个问题呢?
将可滚动控件设置为 DoubleBuffered。
捕获 WM_HSCROLL/WM_VSCROLL 消息。无效。将“do_not_paint”标志设置为真。调用 base.WndProc()。将“do_not_paint”标志设置为 false。更新。
捕获 WM_PAINT 和相关消息。仅当“do_not_paint”标志为假时才调用 base.WndProc()。
这样做是允许可滚动控件执行它需要执行的任何布局计算和滚动条重新定位,但不会让它重绘任何会触发剪切效果的内容。
我将 Application.DoEvents() 添加到 FlowPanel amd 的 Scroll 事件中,该事件停止了我得到的 FlowPanel 子控件的模糊。
有点晚了......但是如果你弄乱了 Color.Transparent,就会发生这种情况。检查您的 FlowLayoutPanel 是否具有透明背景。如果是这样,请尝试改变它。