-1

I have a windows form with many controls on it (mainly text boxes and buttons). Every time I chance the size of the form I change the size and position of the controls so that they are nicely distributed over the form. The problem is that when I change the size of the form it takes up to half a second to redraw all the controls. How can I speed this up?

I have used System.Diagnostics.Stopwatch to time my code and I think that the part that is taking a long time is actually the drawing of the controls on screen (since the math I am doing is completed in less than a millisecond). I have also optimized it so controls are only redrawn when necessary.

One idea I had was to use async functions to draw the controls using several different threads but I don't know much about how forms draw their controls so I don't know if this is possible. This question seems to indicate it's not possible to draw controls from another thread. (I have also never used async programming before and am not sure how I would do it so if this is possible any pointers would be appreciated).

My main questions are:

  • Is it possible to use async programming to do this?
  • Is there another/better way?
Commonaught
  • 340
  • 5
  • 11
  • Do you really have to use WinForms? If you used WPF, all of what you want to achieve would be done automatically. – Xaver Jan 05 '21 at 20:29
  • @Xaver this is a past school project that I am turning into a personal project and I have no experience in WPF. I will take a look at that but depending on the learning curve it might be more work than it's worth. – Commonaught Jan 05 '21 at 20:33
  • Take a look at the Form's `SuspendLayout`, `ResumeLayout` and `PerformLayout` methods. That's why they exist. You *suspend*, move everything around, *resume* and then *perform* it all at once – Flydog57 Jan 05 '21 at 20:45
  • I have tried `SuspendLayout` and `ResumeLayout` with no success but maybe that's because I wasn't using `PerformLayout` – Commonaught Jan 05 '21 at 20:49

1 Answers1

3

Only the UI-thread can update the UI. Therefore multitasking cannot be used to speed up drawing to the UI.

Try setting DoubleBuffered = true; in the form after InitializeComponent();. Sometimes this helps. This setting is often used to reduce flicker.

Are you trying to distribute the controls programmatically? You can use the Anchor property to have winforms do this automatically for you. There is also a FlowLayoutPanel and a TableLayoutPanel. These panels are very helpful for automatic layouts. Even the SplitContainer can be useful for layouting.

If you are making changes to the UI, you can also try to suspend winforms' layouting. This prevents winforms from doing unnecessary calculations and drawing.

SuspendLayout();
try {
    // TODO: Your positioning and sizing logic
} finally {
    ResumeLayout();
}

The try-finally ensures that ResumeLayout runs even in case of an exception, or when you leave the code block with return.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • I will try DoubleBuffer. I have been distributing them programmatically (there are a few fancier things I am doing with controls stretching non-linearly) but I could try some of the methods you mentioned. – Commonaught Jan 05 '21 at 20:43