TableLayoutPanel очень медленно реагирует на события - PullRequest
5 голосов
/ 17 января 2012

В моем приложении мне действительно нужно было разместить много элементов управления (метка, текстовое поле, domainupdown) в хорошем порядке.Поэтому я пошел дальше и использовал несколько вложенных TableLayoutPanel.Проблема в том, что эта форма очень медленно реагирует на большинство событий (изменение размера, максимизация, свертывание и ...). Для элементов управления в таблицах изменение размера и перерисовка до нового размера формы действительно занимает до 5 секунд.

Теперь я кладу палец в глаз!Если эта форма слишком медленная на моем домашнем ПК (i7 @ 4GHz и хорошая графическая карта), что она сделает завтра на старом компьютере P4 на работе?

Я даже пытался использовать приведенный ниже код, но он делаетабсолютно ничего, если это не замедляет это больше!

private void FilterForm_ResizeBegin(object sender, EventArgs e)
{
    foreach(TableLayoutPanel tlp in panelFilters.Controls)
    {
        if(tlp != null)
        {
            tlp.SuspendLayout();
        }
    }
}

private void FilterForm_ResizeEnd(object sender, EventArgs e)
{
    foreach (TableLayoutPanel tlp in panelFilters.Controls)
    {
        if (tlp != null)
        {
            tlp.ResumeLayout();
        }
    }
}

Пожалуйста, дайте мне знать, если есть хитрость, чтобы заставить tablelayoutpanel работать быстрее ... или если вы знаете лучший подход, чтобы сложитьСотня элементов управления прекрасно выровнена.

Ответы [ 2 ]

20 голосов
/ 06 апреля 2012

Используйте этот код.

public class CoTableLayoutPanel : TableLayoutPanel
{
    protected override void OnCreateControl()
    {
        base.OnCreateControl();
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.CacheText, true);
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= NativeMethods.WS_EX_COMPOSITED;
            return cp;
        }
    }

    public void BeginUpdate()
    {
        NativeMethods.SendMessage(this.Handle, NativeMethods.WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
    }

    public void EndUpdate()
    {
        NativeMethods.SendMessage(this.Handle, NativeMethods.WM_SETREDRAW, new IntPtr(1), IntPtr.Zero);
        Parent.Invalidate(true);
    }
}

public static class NativeMethods
{
    public static int WM_SETREDRAW = 0x000B; //uint WM_SETREDRAW
    public static int WS_EX_COMPOSITED = 0x02000000; 


    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); //UInt32 Msg
}
0 голосов
/ 17 января 2012

Если вы создадите новый класс, полученный из TableLayoutPanel, и установите ControlStyles так, чтобы DoubleBuffered было истинно, ваша производительность значительно улучшится.

public class MyPanel :  TableLayoutPanel
{
    public MyPanel()
    {
        this.SetStyle(ControlStyles.DoubleBuffer, true);
    }

}
...