简体   繁体   中英

Prevent redrawing of controls on resize for Windows Forms

I have a TableLayoutPanel which holds a dynamic number of controls inside a SplitterPanel. A user may want to resize the panel to fit these Controls to avoid use of a scroll bar. This creates jitter on the container resize as well as the controls within the container. Sometimes the parent container lags significantly behind movement of the mouse during resize (up to a 3 second lag).

Is there any way to prevent redrawing of Controls during a parent container resize, such as hiding all elements during resize or halting a resize event which occuring during a mousedrag, firing only on an onMouseUp event?

As Hans commented, SuspendLayout and ResumeLayout work well in this situation, along with Suspending the drawing of the control for the container:

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);
  }
}

Then from you resize events:

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();
}

For me it worked well with making the TableLayoutPanel double-buffered, then I didn't even need to suspend the layout. I found the solution on this thread: How to avoid flickering in TableLayoutPanel in c#.net using the double-buffered TableLayoutPanel class from this website: https://www.richard-banks.org/2007/09/how-to-create-flicker-free.html

After that all I needed to do was, after rebuilding the project and restarting Visual Studio a couple of times (to get the InitializeComponent()s working), go inside the .Designer.cs file and change the System.Windows.Forms.TableLayoutPanel class to the new DBLayoutPanel class. To go inside the Designer file and change the class there helped me save time because I already had a lot of controls inside the TableLayoutPanel.

您可以连接父容器的resize事件并将e.Handled或e.Cancel属性设置为true,然后在onMouseUp上进行手动重绘。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM