Click here to Skip to main content
12,404,478 members (70,900 online)
Click here to Skip to main content
Add your own
alternative version

Stats

91.8K views
1.6K downloads
85 bookmarked
Posted

A curtain hiding screen updates, and blending old and new content with a nice fade effect

, 13 Jan 2007
Rate this:
Please Sign up or sign in to vote.
Freeze parts of the user interface until all drawings are done, and blend old content with the new one smoothly.

Purpose

Once in a while, you get an extensive screen update to do. I mean that kind of refresh that invalidates many UI components and makes your desktop application look like a loading webpage. During these updates, many components need to be painted one at a time to obtain the final screen. The problem occurs when the update spans multiple paint events thus making techniques like double buffering hard to use. Worst of all, your users keep complaining about this amateur look and, of course, you don’t feel like an amateur. So you dream of a way to hide your work in progress and only show the end result, don’t you?

This is what this component is all about: freezing parts of the user interface until all drawings are done, even for many paint events. And then, just to sweeten things, the new content is smoothly blended with the old one using a nice fade effect. So now, you get it: this is your chance to add a web 2.0 taste to your desktop application.

If that sounds interesting, here is a Visual Studio 2005 C# loading curtain form ready to be integrated into your project. I named it a “curtain” for it is similar to a theatre curtain which hides actors while they are setting up the next scene.

Why not use the double buffering technique?

Maybe, you’ve heard of the Windows Forms DoubleBuffered property and think that it should work just fine. While it may be handy in some situations, it has some limitations for our problem at hand:

  • Not always possible or easy since some components may not be under your control. For example, when you have a COM component that directly draws itself using a device context, the buffering technique is not an option.
  • Doesn’t span multiple paint events. So when multiple components need to be painted, you have to make sure that they do all at the same time or otherwise, you will end up with the webpage loading syndrome.
  • Not easy to target only parts of the screen.
  • No solution out of the box to apply a fade effect (so forget about the web 2.0 spice).
  • Rather heavyweight when all you want is to hide something for a quarter of a second!

How it works conceptually

  1. Just before updating the UI, you put the curtain over the screen area.
  2. The curtain takes a screen snapshot, and displays this still image to the user.
  3. Meanwhile, you do the hard update work, and rearrange the screen without causing your user an epileptic crisis.
  4. When you’re done, you fade the curtain and let the user see your artwork.

How it works in code

  1. Import the curtain into your project. To do so with Visual Studio 2005, go to ‘Project’, then ‘Add existing item’, and browse for the curtain’s file CurtainForm.cs.
  2. Create your curtain object and configure it. If you want to update multiple UI parts at the same time, you just create multiple curtains!
    MT.CurtainForm myCurtain = new MT.CurtainForm();
  3. Show your curtain in front of the control to be updated (most common case):
    myCurtain.Show(myControl);

    Or manually set the area to be updated:

    myCurtain.Bounds = new Rectangle(x, y, width, height);
    myCurtain.Show();
  4. Finally, fade your curtain:
    myCurtain.Fade();

    Or hide it without the fade effect:

    myCurtain.Hide();

Curtain attributes

These settings are very fine grained, and are provided only for the more fanatical of you!

FadeDuration

Indicates the total time of the fade in milliseconds. Personally, I use a 250ms time since it is not too long to be annoying, and just enough to let the user properly see what has been changed.

FrameDuration

This is the animation accuracy or quality. Like the frames per second in video games, and you can use more or less CPU power. You specify the accuracy by setting the duration of each frame in milliseconds. So if you set 50ms per frame, this is equivalent to 20 frames per second.

ClickThrough

Indicates whether the user can click through the curtain while it is fading. This has no effect when not fading since the goal of the curtain is to hide what's going on behind. Useful when using a long fade duration since the user can interact with the new content immediately.

Limitations

Cannot resize the area while displaying the curtain. To avoid resize, I use the following code in the container form:

Before showing the curtain:

MinimumSize = this.Size;
MaximumSize = this.Size;

Once the curtain is hidden:

MinimumSize = new Size(0,0);
MaximumSize = new Size(0,0);

If your window cannot be resized, then this is not an issue for you.

Example project

The example project consists of two groups of listboxes that can be updated. One group using the curtain, and another that doesn’t. The example illustrates the problem when multiple UI components need to be refreshed: they cannot be refreshed all at the same time. If you find that the listbox update is not really a problem (since calling BeginUpdate and EndUpdate will hide intermediate results after all), imagine that instead of listboxes, we have some cool custom controls.

References

Conclusion

This “curtain technique” is lightweight and reusable whatever the UI components that need to be hidden are. I created it while working with the MSHTML component (the Microsoft HTML editor). I needed a way to hide all the webpage loading work, which is a little bit annoying when editing with a desktop application. Of course, I’m a professional.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Mathieu Jacques
Web Developer
Canada Canada
Software Engineer working at a fun and smart startup company

You may also be interested in...

Comments and Discussions

 
GeneralVery easy to use - thanks! Pin
Ravi Bhavnani7-Jul-11 10:12
memberRavi Bhavnani7-Jul-11 10:12 
GeneralAwesome! Pin
Diamonddrake14-Dec-10 16:16
memberDiamonddrake14-Dec-10 16:16 
GeneralVERY INTERESTING Pin
Johnny J.8-Oct-09 1:58
memberJohnny J.8-Oct-09 1:58 
GeneralRe: VERY INTERESTING Pin
Johnny J.8-Oct-09 2:03
memberJohnny J.8-Oct-09 2:03 
GeneralForm is shown in Alt-Tab menu Pin
miggedy2-Jul-09 5:02
membermiggedy2-Jul-09 5:02 
GeneralUsing AnimateWindow instead of Opacity with timer Pin
Robert Kindl11-Jun-09 4:28
memberRobert Kindl11-Jun-09 4:28 
GeneralPROBLEM: Drawing content flickers through curtain Pin
rayinny1-Aug-07 15:43
memberrayinny1-Aug-07 15:43 
GeneralReturning to a previous window Pin
Miki Watts4-Jun-07 20:03
memberMiki Watts4-Jun-07 20:03 
GeneralRe: Returning to a previous window Pin
Mathieu Jacques5-Jun-07 3:03
memberMathieu Jacques5-Jun-07 3:03 
QuestionCan't quite get this to work... Pin
Miki Watts31-May-07 5:50
memberMiki Watts31-May-07 5:50 
AnswerRe: Can't quite get this to work... Pin
Miki Watts31-May-07 6:44
memberMiki Watts31-May-07 6:44 
QuestionNice control - minor bug? Pin
Davidjwong9-Apr-07 16:08
memberDavidjwong9-Apr-07 16:08 
AnswerRe: Nice control - minor bug? Pin
Mathieu Jacques10-Apr-07 3:22
memberMathieu Jacques10-Apr-07 3:22 
GeneralRe: Nice control - minor bug? Pin
Davidjwong10-Apr-07 11:15
memberDavidjwong10-Apr-07 11:15 
GeneralBUG!! (If RightToLeft changed.) Pin
brian.hawley24-Feb-07 16:21
memberbrian.hawley24-Feb-07 16:21 
GeneralRe: BUG!! (If RightToLeft changed.) Pin
Mathieu Jacques26-Feb-07 3:22
memberMathieu Jacques26-Feb-07 3:22 
GeneralWin32Exception: The handle is invalid [Revisited] Pin
Igor Velikorossov5-Feb-07 19:06
memberIgor Velikorossov5-Feb-07 19:06 
GeneralRe: Win32Exception: The handle is invalid [Revisited] Pin
Mathieu Jacques6-Feb-07 3:30
memberMathieu Jacques6-Feb-07 3:30 
QuestionAutoClose feature / dispose resources ? Pin
CarlosMMartins23-Jan-07 22:31
memberCarlosMMartins23-Jan-07 22:31 
AnswerRe: AutoClose feature / dispose resources ? Pin
Mathieu Jacques24-Jan-07 3:32
memberMathieu Jacques24-Jan-07 3:32 
GeneralRe: AutoClose feature / dispose resources ? Pin
CarlosMMartins24-Jan-07 3:58
memberCarlosMMartins24-Jan-07 3:58 
GeneralRe: AutoClose feature / dispose resources ? Pin
Mathieu Jacques24-Jan-07 4:29
memberMathieu Jacques24-Jan-07 4:29 
GeneralRe: AutoClose feature / dispose resources ? Pin
CarlosMMartins24-Jan-07 4:56
memberCarlosMMartins24-Jan-07 4:56 
Generalgood code Pin
mohsen ahmadian21-Jan-07 20:10
membermohsen ahmadian21-Jan-07 20:10 
GeneralVery Fancy! Pin
crucify17-Jan-07 19:31
membercrucify17-Jan-07 19:31 
GeneralGreat article Pin
CarlosMMartins17-Jan-07 3:12
memberCarlosMMartins17-Jan-07 3:12 
GeneralCode Update - Thanks to Igor Velikorossov Pin
Mathieu Jacques15-Jan-07 3:20
memberMathieu Jacques15-Jan-07 3:20 
GeneralRe: Code Update - Thanks to Igor Velikorossov Pin
Quentin Pouplard16-Jan-07 8:33
memberQuentin Pouplard16-Jan-07 8:33 
GeneralRe: Code Update - Thanks to Igor Velikorossov Pin
Mathieu Jacques16-Jan-07 11:01
memberMathieu Jacques16-Jan-07 11:01 
GeneralWin32Exception: The handle is invalid [modified] Pin
Igor Velikorossov10-Jan-07 14:09
memberIgor Velikorossov10-Jan-07 14:09 
GeneralRe: Win32Exception: The handle is invalid Pin
Mathieu Jacques11-Jan-07 4:21
memberMathieu Jacques11-Jan-07 4:21 
GeneralRe: Win32Exception: The handle is invalid Pin
Igor Velikorossov11-Jan-07 10:56
memberIgor Velikorossov11-Jan-07 10:56 
Generaldual screen problem Pin
Fabrice Deshayes aka Xtream16-Dec-06 6:48
memberFabrice Deshayes aka Xtream16-Dec-06 6:48 
GeneralRe: dual screen problem Pin
Mathieu Jacques18-Dec-06 3:51
memberMathieu Jacques18-Dec-06 3:51 
GeneralBegin/EndUpdate Method Pin
RHarding_19-Dec-06 12:55
memberRHarding_19-Dec-06 12:55 
GeneralRe: Begin/EndUpdate Method Pin
Quentin Pouplard10-Dec-06 6:18
memberQuentin Pouplard10-Dec-06 6:18 
GeneralRe: Begin/EndUpdate Method Pin
Mathieu Jacques10-Dec-06 9:46
memberMathieu Jacques10-Dec-06 9:46 
GeneralRe: Begin/EndUpdate Method Pin
Quentin Pouplard11-Dec-06 9:51
memberQuentin Pouplard11-Dec-06 9:51 
GeneralRe: Begin/EndUpdate Method Pin
Mathieu Jacques12-Dec-06 3:52
memberMathieu Jacques12-Dec-06 3:52 
GeneralCode update Pin
Mathieu Jacques9-Dec-06 4:42
memberMathieu Jacques9-Dec-06 4:42 
GeneralRe: Code update Pin
Quentin Pouplard9-Dec-06 6:50
memberQuentin Pouplard9-Dec-06 6:50 
GeneralProblem with code Pin
H_R_O26-Sep-06 0:02
memberH_R_O26-Sep-06 0:02 
GeneralRe: Problem with code Pin
Mathieu Jacques26-Sep-06 10:51
memberMathieu Jacques26-Sep-06 10:51 
GeneralRe: Problem with code Pin
Mathieu Jacques2-Oct-06 8:59
memberMathieu Jacques2-Oct-06 8:59 
GeneralRe: Problem with code Pin
H_R_O12-Dec-06 21:59
memberH_R_O12-Dec-06 21:59 
GeneralGreat! Pin
Coyotelapa19-Sep-06 0:39
memberCoyotelapa19-Sep-06 0:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160721.1 | Last Updated 14 Jan 2007
Article Copyright 2006 by Mathieu Jacques
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid