为什么用复杂的用户控件子项绘制 FlowLayoutPanel 需要很长时间?

Why painting FlowLayoutPanel with complex user controls childs takes ages?

我正在使用 "FlowLayoutPanel" 来存储复杂的 GUI。 此结构包含两种类型的用户控件:

  1. "S" 简单 U.C(恒定大小)
  2. "C" 另一个 FlowLayoutPanel 可以将它们作为子项键入..等等。

当我有这种结构时:

1.C

  1. S
  2. S
  3. C :

    1.s

    2.C

       1.S
       2.S
    

渲染此控件大约需要 15 秒, 每次此控件可见性更改时,GUI 都会卡住 15+- 秒,直到它渲染整个组件。

*注 1: 复杂的 "C" 控件是自动调整大小的,其中包含 FlowLayoutPanel。添加子组件时,所有 "inner" "C" 组件的高度都会发生变化。 main\master "C" 控件具有固定大小并具有滚动条。

*注 2: 我扩展了 FlowLayoutPanel 以进行一些双缓冲优化:

public 密封 class FlowLayoutPanelEx : FlowLayoutPanel {

    public FlowLayoutPanelEx()
        : 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;
        }
    }

}

通过覆盖 "SuspendLayout" 和 "ResumeLayout" 函数解决,

当我需要绘制此控件并且没有任何更改时,我调用 SuspendLayout 函数,该函数递归地为每个子项调用 "SuspendLayout" 函数。

油漆结束后。 我调用 "ResumeLayout" 做同样的事情。

这将使用户控件不会 "RePaint" 并计算所有 childs\parent 大小,而只是将控件绘制在他之前的相同状态。

将渲染时间从 15 秒减少到 0.2 秒:)