8

I made a windows form with many dropdown list which are placed inside a grid(not a datagrid) and when I use anchor=left right top bottom and dock=fill options in all of them, the form resize gets slow on runtime.

What's the problem with dock and anchor options?

Is it a general problem with forms? Is it a general disadvantage of using .net components and windows forms?

I don't have any custom events handled on control resize, so the problem is about the controls Microsoft developed. Should I avoid using dock=fill?

Uğur Gümüşhan
  • 2,455
  • 4
  • 34
  • 62

2 Answers2

19

It's a normal that it consumes your processor as on every resize move form forms resize table layout panel which forces resize and reposition child controls (dropdowns), as there is anchor property setuped.

There is a trick to avoid to create a frustration for user when resizing:

Use SuspendLayout() and ResumeLayout() on BeginResize() and EndResize() event handlers.

Look here for concrete example:

Prevent window redraw when resizing c# windows forms

Should work for you.

Community
  • 1
  • 1
Tigran
  • 61,654
  • 8
  • 86
  • 123
  • 1
    Actually it is not problem of winform or some layout panel, it's problem of combobox control. It's very slow control, it takes a lot of time on creation and resizing. – 23W Sep 24 '19 at 05:27
  • For me this only works when making the form bigger for some reason. When I make it smaller again, the anchor doesn't update. – Icoryx Oct 20 '22 at 09:57
0

WinForms drawing performance relies exclusively on CPU processor, single-threaded. This means you will face several performance issues if your form draws pictures, or any other complex/numerous UI elements. So you may want to disable unnecessary redrawing events to optimize the overall performance.

The dirty trick below will give you a huge performance gain by disabling redrawing when resizing occurs in your form. This code below should be placed in your form's class:

protected override void OnResize(EventArgs e)
{
    this.SuspendDrawing();
    base.OnResize(e);
    this.ResumeDrawing();
}

protected override void OnResizeBegin(EventArgs e)
{
    this.SuspendDrawing();
    base.OnResizeBegin(e);
}

protected override void OnResizeEnd(EventArgs e)
{
    base.OnResizeEnd(e);
    this.ResumeDrawing();
}

protected override void OnClosing(CancelEventArgs e)
{
    this.SuspendDrawing();
    base.OnClosing(e);
    this.ResumeDrawing();
}

And this is the extension method which does all the trick:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Example
{
    public static class ControlExtensions
    {
        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);

        private const int WM_SETREDRAW = 11;

        public static void SuspendDrawing(this Control control) => SendMessage(control.Handle, WM_SETREDRAW, false, 0);

        public static void ResumeDrawing(this Control control)
        {
            SendMessage(control.Handle, WM_SETREDRAW, true, 0);
            control.Refresh();
        }
    }
}
sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40
  • Downvoted because functions for these things already exist (see accepted answer), so P/Invoke is unnecessary overkill. Plus, your solution requires inheriting from the control. – Sod Almighty Jul 28 '21 at 12:22
  • Well, overkill or not, it works, and it has been commonly used to considerably improve responsiveness. – sɐunıɔןɐqɐp Jul 31 '21 at 17:14
  • So have the built-in functions such as `Control.SuspendLayout()`. Your externs are redundant. – Sod Almighty Aug 02 '21 at 02:47
  • Sorry but you are completely wrong, it has indeed a completely different performance effect, just try it by yourself in a complex WinForms application of yours. – sɐunıɔןɐqɐp Aug 16 '21 at 11:08