views:

79

answers:

2

I am working on a WinForms project which feels sluggish. It is composed of a literally hundreds of User Controls. If there is a piece of a UI functionality (even if not used anywhere else in the app), it's encapsulated in a User Control. I've gone through the project a number of times with the ANTS profiler and most of the heavy code appears to be in various control constructors.

Before I start ripping out User Controls, do they represent significant overhead to a WinForms application versus just laying out the form without User Controls (e.g. just intrinsic controls)?

+3  A: 

I've been in User Control hell and it's not fun. A few things I've noticed:

  1. If you have too many user controls and move your form around or scroll, you can wind up with a lot of white flickering as the drawing operations of deeply nested window handles fight for rendering time. This is particularly noticeable when you first open up the form.

  2. Beware of nested user controls in the designer. If you open a user control in the designer, the constructor won't be called (it actually generates the designer surface by parsing the compiler-generated code.) However, user controls used by that user control will have their constructors called. This is usually not a problem, but it's worth knowing about if you see odd things happening.

  3. If you have a large solution with lots of user controls, VS 2008 will take a long time to enumerate all of your projects to find all possible controls the first time you open the designer pane. This is a relatively minor annoyance, but it can consume time.

That said, User Controls are definitely handy and worth using in moderation. The main thing I try to avoid is overly deep nesting. I've found that WPF is much better in this respect. It has full control over the rendering pipeline, so you don't get the repainting issues associated with deep composition of controls.

Dan Bryant
@Dan Bryant. Good observations. I solved flickering in #1 with some creating style setting ( http://www.angryhacker.com/blog/archive/2010/07/21/how-to-get-rid-of-flicker-on-windows-forms-applications.aspx ). I solved #2 by having each control inherit from a base control that determines whether or not you are in the design mode. #3 was solved by going into Tools/Options/WinForms Designer and turning the AutoToolBoxPopulate off.
AngryHacker
@AngryHacker, interesting work-around for the flickering; I'll have to remember that the next time I do another GUI-heavy WinForms app.
Dan Bryant
+3  A: 

A user control is a container for other controls. Having hundreds of them probably means you have multiple hundreds of windows in your project. A window is a very expensive operating system object. They start to noticeably drag down painting perf when you have more than 50 or so.

The comparison to Outlook is apt. That's a good sized chunk of a program. It has less than 50 windows. Easy to see with Spy++.

The difference is OnPaint. Microsoft wrote a lot of code, they didn't drop a lot of controls on a form.

Hans Passant
+1, exactly, the real problem isn't user controls, but window handles. It's interesting that MS is actually moving away from window handles now with technologies like WPF that handle all of their own drawing in a single window via DirectX. Windowing was a revolutionary concept for its era, but the specific architecture hasn't scaled well as more applications are running and they contain increasingly complicated content.
Dan Bryant
It's always been that way. Notable in VB6 with support for windowless controls. Back in WinForms with the ToolStripItem classes. And, yes, WPF.
Hans Passant