While searching for code to fade a winform, I came across this page on the MSDN forum.
for (double i = 0; i < 1; i+=0.01)
{
this.Opacity = i;
Application.DoEvents();
System.Threading.Thread.Sleep(0);
}
The for
loop has a non-integer increment and, from a previous question I asked, that's not a good programming technique (due to inexact representation of most decimals).
I came up with this alternative.
for (double i = 0; i < 100; ++i)
{
this.Opacity = i/100;
Application.DoEvents();
System.Threading.Thread.Sleep(0);
}
Which of these is more efficient?
If there's a better algorithm for fading a form, I'll be very glad if it is included.
Thanks.
In the past, I've used
AnimateWindow
to fade in/out a generated form that blanks over my entire application inSystemColor.WindowColor
.This neat little trick gives the effect of hiding/swapping/showing screens in a wizard like interface. I've not done this sort of thing for a while, but I used P/Invoke in VB and ran the API in a thread of its own.
I know your question is in C#, but it's roughly the same. Here's some lovely VB I've dug out and haven't looked at since 2006! Obviously it would be easy to adapt this to fade your own form in and out.
is more efficient as the number of floating point divisions are more machine-expensive than compared to floating point additions(which do not affect vm-flags). That said, you could reduce the number of iterations by 1/2(that is change step to i+=0.02). 1% opacity reduction is NOT noticeable by the human brain and will be less expensive too, speeding it up almost 100% more.
EDIT:
Forget timers (pun intended).
With Visual Studio 4.5 or higher, you can just
await
a task that is delayed. An advantage of this method is that it's asynchronous, unlike a threadSleep
orDoEvents
loop, which blocks the application during the fade (and the other aforementionedDoEvents
problems).Usage:
You should check if the object is disposed before you apply any transparency to it. I used a form as the object, but you can pass any object that supports transparency as long as it's cast properly.
So, first off, application.DoEvents should be avoided unless you really know what you're doing and are sure that this is both an appropriate use of it, and that you are using it correctly. I'm fairly certain that neither is the case here.
Next, how are you controlling the speed of the fading? You're basically just letting the computer fade as quickly as it can and relying on the the inherent overhead of the operations (and background processes) to make it take longer. That's really not very good design. You're better off specifying how long the fade should take from the start so that it will be consistent between machines. You can use a
Timer
to execute code at the appropriate set intervals and ensure that the UI thread is not blocked for the duration of the fade (without usingDoEvents
).Just modify the
duration
below to change how long the fade takes, and modify thesteps
to determine how "choppy" it is. I have it set to 100 because that's effectively what your code was doing before. In reality, you probably don't need that many and you can just lower to just before it starts getting choppy. (The lower the steps the better it will perform.)Additionally, you shouldn't be so worried about performance for something like this. The fade is something that is going to need to be measured on the scale of about a second or not much less (for a human to be able to perceive it) and for any computer these days it can do so, so much more than this in a second it's not even funny. This will consume virtually no CPU in terms of computation over the course of a second, so trying to optimize it is most certainly micro-optimizing.
I applied the approach of Victor Stoddard to a splashScreen. I used it in the Form_Load event to fadeIn and FormClosing event to fadeOut. NOTE: I had to set the form's opacity to 0 before call the fadeIn method.
Here you can see the order of events rised by a winform (lifecycle): https://msdn.microsoft.com/en-us/library/86faxx0d(v=vs.110).aspx
I wrote a class specifically for fading forms in and out. It even supports
ShowDialog
and DialogResults.I've expanded on it as I've needed new features, and am open to suggestions. You can take a look here:
https://gist.github.com/nathan-fiscaletti/3c0514862fe88b5664b10444e1098778
Example Usage