防止重新调整Windows窗体的大小调整控件

时间:2012-01-19 16:48:07

标签: c# winforms vsto

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

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

3 个答案:

答案 0 :(得分:3)

正如汉斯评论的那样,SuspendLayoutResumeLayout在这种情况下运作良好,同时暂停了容器控件的绘制:

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

答案 1 :(得分: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中有很多控件。

答案 2 :(得分:0)

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