Form rendering - Panels are drawn and show before the controls within the panel

MattNorman

Well-known member
Joined
May 22, 2021
Messages
98
Programming Experience
1-3
I am trying to get my form loading process to look a bit smoother however all of the options I have tried are failing.

Currently I see the panel render first and then all of the controls within the panel render afterwards.

There's not a huge delay however I want to try get all of the controls to draw at the same time.

I have tried looping through all controls and setting the double buffered property.

I have also tried using SuspendLayout and ResumeLayout on all controls.

On some forms I have also offloaded any loading tasks to a background thread so that it doesn't hold up the UI thread.

These are the only suggestions I have found and none seem to work. I suspect that if I got rid of the panels and just made the form the parent the issue would likely go away however I would prefer to keep the panels.

Does anyone have any suggestions that may help?
 
I don't care what section it is or where you posted it. If you want to draw objects/controls/or have faster render times etc, then you picked the wrong project type. Winforms is not the best solution for doing any of these things. It is not a good solution for working with anything that involves moving objects or rendering controls at a decent speed especially if your form has many controls. The calculative performance speed tests done by myself and various other devs can vouch for this. Double buffering can only do so much and there are no other properties which you can set nor are there any methods you can call to help with the crappy performance you will get with a Winforms app.

A common mistake new developers make; is not properly doing their research before diving into their project. Most developers pick what appears to be easiest.

Before committing to this app. Had you asked which project type should I use if I want a scalable high performance UI for a desktop app. You would have been told the same thing as I said above by a majority of developers who know how efficient WPF is in comprising. WPF is immanently better, and if your app is already built, then you likely made a fatal mistake in choosing a clunky piece of crap like Winforms to build it.
 
Alternatively, if you wrote your app correctly, your UI would have been disconnected from your program logic. Moving your app from one UI framework (e.g. WinForms) to another UI framework (e.g. WPF) should be relatively easy if you followed one of the modern architectures like MVC, MVP, MVVM, etc. Notice how the Model (the first M) is separate from the View, and how also how the program logic (e.g. the Controller, Presenter, or View Model) also also separate from the View.
 
Currently I see the panel render first and then all of the controls within the panel render afterwards.

... I want to try get all of the controls to draw at the same time.

On some forms I have also offloaded any loading tasks to a background thread ...
Off loading the work to another thread guarantees asynchrony. When you are in an asynchronous situation, then you can't expect all of the controls to render all at the same time because now each of your controls will finish it's work at the time it has data ready to be rendered. The idea of offloading the work to other threads is to free up the main UI thread so that the user doesn't experience lag when they are trying to interact with the UI. It does not make less work happen. All it does is allow the same amount of work be potentially done in less time because you can now do work in parallel instead of sequentially. If any of the pieces of work to be done still takes a significant amount of time and it can't further be improved by taking advantage of threads, then you have no choice but let the user wait for the work to complete, and for the UI to reflect when that work completes.
 
Does anyone have any suggestions that may help?
Yes. It's time to fall back on the older Win3.x tricks of the trade:
splash screens -- prepare everything ahead of time before first rendering the active UI
off screen renders -- which is what double buffering was originally all about,
only paint during the WM_PAINT event
only paint what is is the update region
minimize the size of the update region
bypassing the WM_ERASEBACKGND if you know that your WM_PAINT is going to cover the entire screen
limiting the layering of controls
limiting the number of controls -- This is why WPF excels in speed because at render time everything draws to an off screen buffer, and then slammed into the screen buffer when all the UI elements are done rendering.
using invisible/snapshot windows to act as a screen -- Sometimes you don't have control over the controls that you are using and no amount of double buffering works, so the best you can do is take a screenshot of the current window, and then plop a window the same size as your UI in front of your UI with the screenshot. You then update your actual window. When completed, you take away the screenshot window. Tada! Instant render.

A lot of the above tricks of the trade have fallen to wayside with the advent of faster multithreaded machines, and GPU assisted GDI/GDI+ rendering. Some of those tricks are a direct result of learning from the WM_PAINT documentation.

 
@Skydiver Some of your above recommendations ( i am aware they are not proposed solutions ) they are intended 'hacks/tricks', and workarounds for a shitty project type that Winforms is. While your post is helpful in some aspects, I wouldn't recommend them to others for the simple fact that 'most' developers are slow to migrate to better platforms such as the WPF/UWP type project types, and they are also reluctant to change or try and learn something new like WPF because they'd rather put their fate in ancient 'hacks/tricks' and or risk the mobility of portability to another architecture just to avoid the learning curve or the additional work involved with porting to something like WPF for the simplicity of your proposals.

We should be encouraging people to not be stuck in the past, and move with the times. As helpful as some of your suggestions may be, they are not solutions, and nobody reading this should misconstrue them as such. Because they really aren't. It's my opinion that posts like the above actually hold people back from making or trying to make the transition to the more modern improved architectures available to us today. Any developer trying to transition to WPF would be best following the MVP pattern than any of the others. Why? It would make transitioning process between the two much easier. Once they have a working and successful port from Winforms, they can effortlessly alter their design pattern from MVP to include the VM pattern if they want. The MVVM pattern is not always a requirement for WPF, despite it being the favoured development pattern. MVVM guides us devs on how to distribute responsibilities between classes in a UI application, but it's not always a requirement either as much as I too approve of its uniqueness. Every pattern is specific to the specifications and complexity of the application being designed.

Trying my best here not to derail the topic into a Winforms VS WPF topic. The most honest answer that can be given here is to move your application to a platform architecture capable of doing what you require. Clearly, Winforms failed the OP's performance expectations. While this is not the answer they want to hear, it's the best one they will get.
 
Winforms is just a thin wrapper around the original Windows controls. The list I had above for various things we did back in the Windows 3.x days before multicore processors to get the most out of our Windows apps written using the original Windows controls.

Yes, there are better alternatives like WPF for desktop UI development. I was just offering options for the OP if he is really stuck with WinForms because he didn't design his code properly by following one of the MV* patterns so that he could easily swap out his V.
 
This will sound heartless...

If you are using a Winforms app, and you are really stuck. Then take your code and work on porting it to WPF/UWP. There is no middle ground here for "I'm just trying to help them in a worse case scenario". Posts like yours stop people from advancing. We need people to move the heck forward. Don't get me wrong, I respect the knowledge and information you are giving for someone "stuck" in that position, but it's shite. And all it does in my opinion is keeps people clinging on to posts like yours as a viable excuse to not do the right thing and move to the a modernised architecture; and all because your post puts a plaster on their problem...
 
Yup. Sometimes it is time to give up the bow and arrow, and move on to a BMG-50. The old saying it "It's the Indian, not the arrow" has to give way to "It's the .50 caliber, not the sniper." :)
 
Exactly, and it's better to persuade them to move on than to teach them old tricks which only hold them back. If you put a 50CC motor into a mini, you can't expect to beat a 7 series BMW at the traffic lights at take off. OP needs to upgrade!
 
Back
Top Bottom