防止在 Windows 窗体调整大小时重绘控件

sam*_*cow 3 c# vsto winforms

我有一个 TableLayoutPanel,它在 SplitterPanel 内保存动态数量的控件。用户可能希望调整面板大小以适合这些控件,以避免使用滚动条。这会在容器大小调整以及容器内的控件上产生抖动。有时,在调整大小期间,父容器会明显滞后于鼠标的移动(最多 3 秒的滞后)。

有什么方法可以防止在父容器调整大小期间重新绘制控件,例如在调整大小期间隐藏所有元素或停止在 mousedrag 期间发生的调整大小事件,仅在 onMouseUp 事件上触发?

Lar*_*ech 5

正如汉斯评论的那样,在这种情况下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);
  }
}
Run Code Online (Sandbox Code Playgroud)

然后从您调整事件大小:

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 调用控件的 SuspendLayout 和 ResumeLayout 方法可以提供帮助的少数情况之一。它在调整大小时保持 TLP 内容可见且不闪烁。 (3认同)