动态填充TableLayoutPanel中的性能下降
-
21-08-2019 - |
题
我有一个包含一个2列和TableLayoutPanel中接受命令动态地添加行,以显示在单独的控制选择的项目的详细信息的用户控制。因此,用户将选择其他控制(一个DataGridView)一行,在DataGridView中的SelectedItemChanged事件处理我清楚详细控制,然后重新生成新的选择项中的所有行(可能有完全不同的细节从先前选择的项目显示)。这一阵子的伟大工程。但是,如果我不断从一个选定的项目移动到另一个相当长的一段时间内,刷新变得非常慢(3-5各秒)。这使得它听起来像我不恰当地处置一切,但我想不出什么我失踪。这里是我的代码用于清除TableLayoutPanel中的:
private readonly List<Control> controls;
public void Clear()
{
detailTable.Visible = false;
detailTable.SuspendLayout();
SuspendLayout();
detailTable.RowStyles.Clear();
detailTable.Controls.Clear();
DisposeAndClearControls();
detailTable.RowCount = 0;
detailTable.ColumnCount = 2;
}
private void DisposeAndClearControls()
{
foreach (Control control in controls)
{
control.Dispose();
}
controls.Clear();
}
和一旦我装完了所有的控制我要到TableLayoutPanel中对这里的未来细节显示就是我所说的:
public void Render()
{
detailTable.ResumeLayout(false);
detailTable.PerformLayout();
ResumeLayout(false);
detailTable.Visible = true;
}
我没有使用TableLayoutPanel中里的任何东西,但标签(和一个TextBox很少),我添加标签和文本框的控件列表(在DisposeAndClearControls引用())当我创建它们。我尝试了迭代detailTable.Controls和处理他们的方式,但它似乎错过一半的控制(通过它在调试器步进确定)。这样,我知道我让他们所有。
我很感兴趣的任何建议,以改善绘图性能,而且特别是什么造成了多重选择的退化。
解决方案 3
我改变了含有的形式只是构造上的每个选择变化我的用户控制的新版本。它作主旧之一,构造一个新的。这似乎执行得很好。我本来已经走带反正重用只是一个性能方面的原因。显然,不提高性能。而且性能不是一个问题,如果我处理旧的,创造一个新的。
不幸的是,TableLayoutPanel中泄漏那样的,虽然。
其他提示
只要使用从TableLayoutPanel中继承的自定义控制,并设置在真DoubleBuffered财产,伟大工程......尤其是当你动态添加或删除行。
public CustomLayout()
{
this.DoubleBuffered = true;
InitializeComponent();
}
我跟TableLayout类似的问题。如果我用的 TableLayout.Controls.Clear()方式,孩子得了控件从来没有布置,但是当我只是放弃了TableLayout不清除它,泄漏停止。现在回想起来,这很有趣,我使用了Clear方法的阻止的某种泄漏。
显然,清除方法不明确处置的控件(这是有道理的,因为你从TableLayout删除他们的事实并不意味着你与他们所做的),并从TableLayout删除的子控件防止清除例程当LayoutTable本身得到处理处置的孩子(它根本不知道它们了)。
我的建议:删除 detailTable.Controls.Clear(); 线,从父母的控件集合中删除的detailTable本身和处理它,然后创建一个新品牌TableLayout下一轮。同时也失去了DisposeAndClearControls方法完全因为你不再需要它。根据我的经验,它的工作很好。
这样,您就不必再回收整个用户的控制,但仅在TableLayout。
我面临同样的问题,并发现一种好方法,而不改变太多:
在VB.net
Dim tp As Type = tlpMyPanel.GetType().BaseType
Dim pi As Reflection.PropertyInfo = _
tp.GetProperty("DoubleBuffered", _
Reflection.BindingFlags.Instance _
Or Reflection.BindingFlags.NonPublic)
pi.SetValue(tlpMyPanel, True, Nothing)
或在C#:
Type tp = tlpMyPanel.GetType().BaseType;
System.Reflection.PropertyInfo pi =
tp.GetProperty("DoubleBuffered",
System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic);
pi.SetValue(tlpMyPanel, true, null);
不幸的是,我能够提供的唯一建议就是把你自己控制的位置的照顾。在我的经验.NET TableLayoutPanel中,而非常有用的,漏水的东西,随着它的增长unusably慢(和它没有考虑细胞的数量不合理拿到了这一点,无论是)。此行为可以在设计被视为良好。
TableLayoutPanel.Controls.Clear()工作正常,我,也许它因为我清除它从一个不同的标签比其显示在
List<Control> controls = new List<Control>();
foreach (Control control in tableLayoutPanelEnderecoDetalhes.Controls)
{
controls.Add(control);
}
foreach (Control control in controls)
{
control.Dispose();
}