8

这真的很简单。

我有一个 TableLayoutPanel,它基于数据库查询填充了控件(只是标签、按钮和一些带有按钮的面板)。当需要刷新数据时,我使用 TableLayoutPanel.Controls.Clear()。不幸的是,这是一个非常缓慢的操作。我希望它比填充表格的代码快,但它至少慢 3 或 4 倍。

我明确地证明了缓慢是在执行 Controls.Clear() 时,通过在显示消息框后将其作为对 TableLayoutPanel 完成的单一操作执行(然后过程返回)。控件从下往上明显消失。当使用记录集重新填充 TableLayoutPanel 时,控件从上到下出现的速度几乎比我看到的要快。

我已经在做 TableLayoutPanel.SuspendLayout() 和 ResumeLayout()。

在表单上使用this.DoubleBuffered = true似乎没有任何作用。

我可以只处理整个控件并通过代码重新创建它,但这是一个很大的痛苦,并且使拥有一个漂亮的表单设计器 GUI 毫无意义。我必须深入研究我在控件上设置的每个属性并为其创建一行代码(尽管我想我可以从设计器代码本身中得到它,但它仍然感觉不对)。

关于如何更快地完成工作的任何想法?我什至愿意使用除 TableLayoutPanel 之外的其他方法......我只需要自由地在每个单元格中放置多个按钮,或者禁止它能够跨越表格标题中的列。

C# 至少可以在重绘时冻结整个表单,然后一次全部绘制吗?

4

4 回答 4

9

我也遇到了使用 TableLayoutPanels 的缓慢问题。我发现最好的解决方案不是在表单上设置 DoubleBuffered 属性,而是创建一个继承自 TableLayoutPanel 的新类,并在该类的构造函数中启用双缓冲:

public class DoubleBufferedTableLayoutPanel : TableLayoutPanel
{
    public DoubleBufferedTableLayoutPanel()
    {
        DoubleBuffered = true;
    }
}

然后,在通常使用 TableLayoutPanel 的任何地方使用 DoubleBufferedTableLayoutPanel。

于 2010-10-12T19:50:03.093 回答
6

这似乎适用于我的用途:

tableLayoutPanel.Visible = false;
tableLayoutPanel.Clear();
/* Add components to it */
tableLayoutPanel.Visible = true;
于 2012-04-15T00:03:31.150 回答
3

无需TableLayoutPanelChris Ryan 的回答那样进行子类化。我有同样的问题并通过反射设置属性来解决它:

typeof(TableLayoutPanel)
   .GetProperty("DoubleBuffered",
      System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
   .SetValue(myTableLayoutPanel, true, null);
于 2015-02-10T16:43:02.183 回答
0

如果我要构建一些动态 gui,我总是会在代码中这样做。但在一开始,我只是从设计人员开始设计一个虚拟表单,并按照我(或更好的客户)喜欢的方式来设置每个控件的样式。然后我查看 Designer.cs 文件并将必要的属性设置从中复制到一些工厂函数中,例如

private TextBox CreateTextBox(string name, /* maybe other parameters */)
{
    var textBox = new TextBox();
    textBox.Name = name;
    //Other settings from given parameters...

    //Further settings which are all the same for these kind of control
    textBox.KeyDown += (sender, e) => {};

    return textBox;
}

所以我确保每个控件在我的 GUI 上的感觉和外观都是一样的。这将在我的表面内的每个级别上完成(从像这样的小控件开始,TextBox一直到像GroupBoxor之类的容器TableLayoutPanel

在某些情况下,这会导致工厂函数调用其他几个工厂函数。如果这成为现实,那么是时候考虑将这些控件封装到单个中了UserControl,但与往常一样,这取决于是否需要这样做。

从我的角度来看,我只能鼓励您将代码从设计器中移出到自己编写的函数中。一开始它(一如既往)需要更多的工作,但之后对布局进行更大的更改会更容易。

于 2010-08-11T07:33:32.480 回答