Best winform extinction algorithm

While searching for code to fade 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, on the previous question, I asked what is not a good programming method (due to the inaccurate representation of most decimal places).

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 one is more effective?

If there is a better algorithm for fading the form, I will be very happy if it is turned on.

Thanks.

+7
source share
6 answers

Forget the timers (pun intended).

With Visual Studio 4.5 or higher, you can simply await to delay the task. The advantage of this method is that it is asynchronous, unlike the Sleep or DoEvents , which blocks the application during decay (and the other DoEvents problems mentioned above).

 private async void FadeIn(Form o, int interval = 80) { //Object is not fully invisible. Fade it in while (o.Opacity < 1.0) { await Task.Delay(interval); o.Opacity += 0.05; } o.Opacity = 1; //make fully visible } private async void FadeOut(Form o, int interval = 80) { //Object is fully visible. Fade it out while (o.Opacity > 0.0) { await Task.Delay(interval); o.Opacity -= 0.05; } o.Opacity = 0; //make fully invisible } 

Using:

 private void button1_Click(object sender, EventArgs e) { FadeOut(this, 100); } 

You must check if the object is before applying transparency to it. I used the form as an object, but you can pass any object that supports transparency while it displays correctly.

+15
source

So, firstly, application.DoEvents should be avoided if you really donโ€™t know what you are doing and are sure that this is an appropriate use and that you are using it correctly. I am absolutely sure that this is not so.

Then, how do you control the speed of fading? You basically just let the computer fade as fast as you can, and rely on the overhead of operations (and background processes) to make this take more time. This is really not a good design. Youโ€™d better clarify how long it takes to fade out from the start so that it is consistent between machines. You can use Timer to execute the code at appropriate intervals and make sure that the user interface thread is not blocked for the time of fading (without using DoEvents ).

Just change the duration below to change how long the fade takes and change the steps to determine how โ€œfadingโ€ it is. I have 100 installed because it is effectively what your code did before. In fact, you probably don't need a lot, and you can just go down before you start to hesitate. (The lower the steps, the better it will be.)

Plus, you shouldn't worry so much about performance for something like that. Attenuation is something that needs to be measured on a scale of about a second or not much less (so that a person can perceive it), and for any computer these days it can do it, much more than this per second is not even funny. It will consume almost no processor in terms of computing within a second, so an attempt to optimize it will certainly be micro-optimization.

 private void button1_Click(object sender, EventArgs e) { int duration = 1000;//in milliseconds int steps = 100; Timer timer = new Timer(); timer.Interval = duration / steps; int currentStep = 0; timer.Tick += (arg1, arg2) => { Opacity = ((double)currentStep) / steps; currentStep++; if (currentStep >= steps) { timer.Stop(); timer.Dispose(); } }; timer.Start(); } 
+12
source
 for (double i = 0; i < 1; i+=0.01) { this.Opacity = i; Application.DoEvents(); System.Threading.Thread.Sleep(0); } 

more efficient, since the number of floating point divisions is spent more on the machine than in comparison with floating point additions (which do not affect vm flags). However, you can reduce the number of iterations by 1/2 (this is the change step to i + = 0.02). A 1% reduction in opacity is NOT noticeable by the human brain and will be less expensive, speeding it up almost 100% more.

EDIT:

 for(int i = 0; i < 50; i++){ this.Opacity = i * 0.02; Application.DoEvents(); System.Threading.Thread.Sleep(0); } 
+3
source

I applied Victor Stoddard's approach to splashScreen. I used it in the Form_Load event for the fadeIn event and FormClosing for fadeOut. NOTE. I had to set the opacity of the form to 0 before calling the fadeIn method.

Here you can see the order of events caused by winform (life cycle): https://msdn.microsoft.com/en-us/library/86faxx0d(v=vs.110).aspx

 private void Splash_Load(object sender, EventArgs e) { this.Opacity = 0.0; FadeIn(this, 70); } private void Splash_FormClosing(object sender, FormClosingEventArgs e) { FadeOut(this, 30); } private async void FadeIn(Form o, int interval = 80) { //Object is not fully invisible. Fade it in while (o.Opacity < 1.0) { await Task.Delay(interval); o.Opacity += 0.05; } o.Opacity = 1; //make fully visible } private async void FadeOut(Form o, int interval = 80) { //Object is fully visible. Fade it out while (o.Opacity > 0.0) { await Task.Delay(interval); o.Opacity -= 0.05; } o.Opacity = 0; //make fully invisible } 
+1
source

In the past, I used AnimateWindow to fade in / out of a generated form that runs through my entire application in SystemColor.WindowColor .

This neat little trick gives the effect of hiding / replacing / displaying screens in the wizard interface. I haven't done this for a while, but I used P / Invoke in VB and ran the API in my thread.

I know your question is in C #, but this is about the same. Here are some great VBs that I dug up and haven't watched since 2006! Obviously, it would be easy to adapt this to wash your own form.

 <DllImport("user32.dll")> _ Public Shared Function AnimateWindow(ByVal hwnd As IntPtr, ByVal dwTime As Integer, ByVal dwFlags As AnimateStyles) As Boolean End Function Public Enum AnimateStyles As Integer Slide = 262144 Activate = 131072 Blend = 524288 Hide = 65536 Center = 16 HOR_Positive = 1 HOR_Negative = 2 VER_Positive = 4 VER_Negative = 8 End Enum Private m_CoverUp As Form Private Sub StartFade() m_CoverUp = New Form() With m_CoverUp .Location = Me.PointToScreen(Me.pnlMain.Location) .Size = Me.pnlMain.Size .FormBorderStyle = System.Windows.Forms.FormBorderStyle.None .BackColor = Drawing.SystemColors.Control .Visible = False .ShowInTaskbar = False .StartPosition = System.Windows.Forms.FormStartPosition.Manual End With AnimateWindow(m_CoverUp.Handle, 100, AnimateStyles.Blend) 'Blocks Invoke(New MethodInvoker(AddressOf ShowPage)) End Sub Private Sub EndFade() AnimateWindow(m_CoverUp.Handle, 100, AnimateStyles.Blend Or AnimateStyles.Hide) m_CoverUp.Close() m_CoverUp = Nothing End Sub 
0
source

I wrote a class specifically for attenuating forms in and out. It even supports ShowDialog and DialogResults.

I expanded it as I need new features and I am open to suggestions. You can look here:

https://gist.github.com/nathan-fiscaletti/3c0514862fe88b5664b10444e1098778

0
source

All Articles