2012-01-17 3 views
4

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

Я сейчас пашу пальцем в глаза! Если эта форма медленная на моем домашнем ПК (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 работать быстрее ... или если вы знаете, лучший подход к улегся около ста управления хорошо выровнены.

+1

Наличие меньшего количества элементов управления будет окончательным решением этой проблемы. – LarsTech

+0

Это было бы идеально ... Но есть моменты, когда вам действительно нужны эти элементы управления! –

+0

Существуют способы ограничения элементов управления. Иногда вы можете исключить ярлыки и просто нарисовать текст в событии рисования. Возможно, рассмотрим [этот ответ] (http://stackoverflow.com/a/8930446/719186), поскольку это звучит так, как будто это может быть одна и та же проблема. Кстати, вам, вероятно, не нужно проходить через элементы управления, как вы, попробуйте просто использовать 'panelFilters.SuspendLayout();' и посмотреть, что произойдет. – LarsTech

ответ

17

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

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 
} 
+3

Большая реализация. У меня был tpl с 70 элементами управления, которые потребовались бы 10 секунд для рендеринга. С этим изменением это мгновенно. –

+0

Похоже на помощь. Графический рисунок, как представляется, происходит сразу с этим. – mbomb007

+1

@ NET3 вы можете ответить [это] (http://stackoverflow.com/questions/43198712/improving-performance-of-tablelayoutpanel-winform)? –

0

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

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

} 
+1

Хорошо спасибо, но это не изменило ничего хорошего, как я могу сравнить! –