2012-01-19 2 views
1

У меня есть TableLayoutPanel, который содержит динамическое количество элементов управления внутри SplitterPanel. Пользователь может захотеть изменить размер панели в соответствии с этими элементами управления, чтобы избежать использования полосы прокрутки. Это создает дрожание на размер контейнера, а также элементы управления в контейнере. Иногда родительский контейнер значительно отстает от движения мыши во время изменения размера (до 3 секундного запаздывания).Предотвращение перерисовки элементов управления при изменении размера для форм Windows

Есть ли способ предотвратить перерисовку элементов управления во время изменения размера родительского контейнера, например, скрыть все элементы во время изменения размера или приостановить событие изменения размера, которое происходит во время муссаграфа, только при запуске события onMouseUp?

ответ

3

Как Ганс заметил, SuspendLayout и ResumeLayout хорошо работать в этой ситуации, наряду с Приостановка рисунок управления для контейнера:

public static class Win32 { 

    public const int WM_SETREDRAW = 0x0b; 

    [DllImport("user32.dll")] 
    public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 

    public static void SuspendPainting(IntPtr hWnd) { 
    SendMessage(hWnd, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero); 
    } 

    public static void ResumePainting(IntPtr hWnd) { 
    SendMessage(hWnd, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero); 
    } 
} 

Тогда от вас изменить размер события:

private void Form1_ResizeBegin(object sender, EventArgs e) { 
    tableLayoutPanel1.SuspendLayout(); 
} 

private void Form1_ResizeEnd(object sender, EventArgs e) { 
    Win32.SuspendPainting(tableLayoutPanel1.Handle); 
    tableLayoutPanel1.ResumeLayout(); 
    Win32.ResumePainting(tableLayoutPanel1.Handle); 
    this.Refresh(); 
} 
+3

Один из немногих случаев, когда вызов метода SuspendLayout и ResumeLayout может помочь. Он сохраняет содержимое TLP видимым и без мерцания при изменении размера. –

+0

@ HansPassant Да, это работает лучше на тонну. Благодарю. – LarsTech

+1

Сохраните подавление перерисовывания, оберните его вокруг ResumeLayout, чтобы он не рисовал дважды. –

0

Вы можете подключить событие изменения размера родительского контейнера и установить для свойства e.Handled или e.Cancel значение true, а затем выполнить ручную перемотку onMouseUp.

1

Для мне это хорошо работало, чтобы сделать TableLayoutPanel двойной буферизацией, тогда мне даже не нужно было приостанавливать макет. Я нашел решение по этой теме: How to avoid flickering in TableLayoutPanel in c#.net с использованием двойной буферизацией класса TableLayoutPanel с этого сайта: https://www.richard-banks.org/2007/09/how-to-create-flicker-free.html

После этого мне нужно было сделать, после восстановления проекта и перезапуска Visual Studio несколько раз (чтобы получить InitializeComponent() работает), зайдите в файл .Designer.cs и измените класс System.Windows.Forms.TableLayoutPanel на новый класс DBLayoutPanel. Чтобы войти в файл Designer и изменить класс, это помогло мне сэкономить время, потому что у меня уже было много элементов управления в TableLayoutPanel.

Смежные вопросы