为什么用复杂的用户控件子项绘制 FlowLayoutPanel 需要很长时间?
Why painting FlowLayoutPanel with complex user controls childs takes ages?
我正在使用 "FlowLayoutPanel" 来存储复杂的 GUI。
此结构包含两种类型的用户控件:
- "S" 简单 U.C(恒定大小)
- "C" 另一个 FlowLayoutPanel 可以将它们作为子项键入..等等。
当我有这种结构时:
1.C
- S
- S
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 秒:)
我正在使用 "FlowLayoutPanel" 来存储复杂的 GUI。 此结构包含两种类型的用户控件:
- "S" 简单 U.C(恒定大小)
- "C" 另一个 FlowLayoutPanel 可以将它们作为子项键入..等等。
当我有这种结构时:
1.C
- S
- S
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 秒:)