How to prevent UI from redrawing every control one by one
In my user control I perform a lengthy operation. In order to prevent users from clicking the UI, I show a progress bar and I disable the whole UI, like this:
this.Enabled = false;
Sh开发者_如何学编程owProgressBar();
DoLengthyOperation();
RemoveProgressBar();
this.Enabled = true;
This works OK. However, my user control has many other controls on it, which also have controls inside them, which also have controls inside them,... etc. The
this.Enabled = false
call thus disables many many controls. This is intentional. But the problem I have is that you can actually see the UI disabling every control one by one. It goes pretty fast but since there are so many controls, you can actually see it running through all the controls. This does not look professional, it makes the screen flicker and my eyes hurt.
Is there a way so that I can prevent the UI from redrawing until all controls are disabled and then perform a single redrawing?
I hope this is not a stupid question ;)
Don't know if this is relevant: my controls are derived from DevExpress.XtraEditors.XtraUserControl.
Have you tried the Form.SuspendLayout and Form.ResumeLayout? It seems like what you need. There is more information on the msdn site here.
You call suspendlayout before you want to re-draw and then resume once you have disabled all the controls.
this.SuspendLayout();
ShowProgressBar();
DoLengthyOperation();
RemoveProgressBar();
this.ResumeLayout();
If the progress bar is on the form, you will have to 'show' it before you suspend the layout. Sorry, I missed that.
try this:
this.Invalidate(); // Invalidate the whole window
this.Enabled = false;
this.Refresh(); // Redraw every invalidated part of the window, so everything
None of the suggestion solutions seems to work.
I think part of the problem is that I use DevExpress and every control does not directly contain its subcontrol, but uses LayoutControlGroups and LayoutControls and panels etc. The actual amount of controls used is thus a lot higher than the actual controls that you see on the screen and that need to be disabled.
So I just added my own recursive function that disables only controls of certain types, in my case Buttons and Edit boxes. The rest is just ignored. Not only is this a lot faster, it also looks much nicer. No flickering at all any more.
I think I'm going to use this solution, but I do appreciate the effort of everyone who put an answer or a comment here, thanks!
Now I see that my question seems to be a duplicate of this one: How do I suspend painting for a control and its children? Haven't tried that solution tough.
You can try and add double buffering to your controls. This will not stop the painting. However, it should help with the visual portion of your issue.
System.Reflection.PropertyInfo aProp =
typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(YourControlNameHere, true, null);
Note: Most controls already have this set to true by default. Your usercontrol may not, so you can test to see if this helps or not.
You can place controls into a container (call it groupControls), Turn the container's visible property to false, (have a splash screen appear or equivalent size container with "updating" or whatever become visible - call it groupUpdateSplash) update your controls turn off splash container visible and turn on your control container visible
groupControls.visible = false
groupUpdateSplash.visible = true
/* update controls and everything */
groupUpdateSplash.visible = false
groupControls.visible = true
精彩评论