8

This might seem like a simple question...

I'm looking for the Label.Opacity property in C# Winforms.

What I wish to do is have a method that fade's out a label gradually. By means of a timer perhaps?

Since there is not Opacity I'm trying to set it's transperency to higher numbers untill it's high enough that the item should be invisible. But I can't seem to make this work.

Currently I have:

public FadeLabel()
{
    MyTimer timer = new MyTimer();
    this.TextChanged += (s, ea) =>
    {
        if (timer.IsActive)
        {
            timer.Reset();
        }
        else
        {
            timer.WaitTime.Miliseconds = 500;
            timer.Start();
            timer.Completed += (a) =>
            {
                int i = 0;
                Timer tm = new Timer();
                tm.Interval = 1;
                tm.Tick += (sa, aea) =>
                {
                    i++;
                    this.ForeColor = Color.FromArgb(i, Color.Black);
                    this.BackColor = Color.FromArgb(i, Color.White);
                    this.Invalidate();
                    if (i == 255)
                    {
                        tm.Stop();
                    }
                };
                tm.Start();
            };
        }
    };
}
Theun Arbeider
  • 5,259
  • 11
  • 45
  • 68

5 Answers5

13

This is what I'm using to fade out labels:

    label1.Text = "I'm fading out now";
    label1.ForeColor = Color.Black;
    timer1.Start();

    private void timer1_Tick(object sender, EventArgs e)
    {
        int fadingSpeed = 3;
        label1.ForeColor = Color.FromArgb(label1.ForeColor.R + fadingSpeed, label1.ForeColor.G + fadingSpeed, label1.ForeColor.B + fadingSpeed);

        if (label1.ForeColor.R >= this.BackColor.R)
        {
            timer1.Stop();
            label1.ForeColor = this.BackColor;
        }
    }

Maybe not the best solution but I'm still a beginner so this is what I can contribute with. I put timer1.Interval at minimum and played with fadingSpeed until it looked good.

Zerato
  • 683
  • 9
  • 18
  • 1
    For anyone not familiar with timers make sure you add: `System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();` and `timer1.Tick += new EventHandler(timer1_Tick);` before the `Start()` – Automate This Aug 16 '17 at 18:11
4

One way that I've found to create a smooth fade is to adjust the ForeColor RGB variables using a timer. This gives you control over the duration and allows you to finesse the transition from current ForeColor values to the target values.

private void timer1_Tick(object sender, EventArgs e)
    {
        // timer interval set to 10 to ensure smooth fading
        // declared int: r = 0, g = 215 and b = 180
        // target values are r = 32, g = 32 and b = 32 to match BackColor
        fade++;
        if (fade >= 500) // arbitrary duration set prior to initiating fade
        {
            if (r < 32) r++; // increase r value with each tick
            if (g > 32) g--; // decrease g value with each tick
            if (b > 32) b--; // decrease b value with each tick
            label1.ForeColor = Color.FromArgb(255, r, g, b);
            if (r == 32 && g == 32 && b == 32) // arrived at target values
            {
                // fade is complete - reset variables for next fade operation
                label1.ForeColor = Color.FromArgb(255, 0, 215, 180);
                label1.Text = "";
                fade = 0;
                r = 0;
                g = 215;
                b = 180;
                timer1.Enabled = false;
            }
        }
    }
BJS3D
  • 149
  • 1
  • 11
3

Does your timer block the UI thread? If so, you won't see anything until after it elapses. A quick way to fix things will be to call Application.DoEvents instead of this.Invalidate();.

Anton Gogolev
  • 113,561
  • 39
  • 200
  • 288
  • actually.. in my current code the second timer is initiated but the tick isn't reached by the code. The "MyTimer" class is a count down class – Theun Arbeider Mar 29 '11 at 10:43
1

This is a more complete and elegant solution:

// Aufruf der Methode aus dem Worker-Thread
private void OnFadeTimerEvent(object sender, ElapsedEventArgs e)
{
    this.Invoke(new Action(() => FadeOutLabel()));
}

private void FadeOutLabel()
{
    if (labelStartHelp.ForeColor.GetBrightness() <= 0.01)
    {
        FadeTimer.Enabled = false;
        labelStartHelp.Visible = false;
        return;
    }
    HslColor hsl = new HslColor(labelStartHelp.ForeColor);
    hsl.L -= 0.002; // Brightness is here lightness
    labelStartHelp.ForeColor = (System.Drawing.Color)hsl.ToRgbColor();
}

using APCyotek HslColor class: http://cyotek.com/downloads/view/Cyotek.Windows.Forms.ColorPicker.zip/Cyotek.Windows.Forms.ColorPicker/Cyotek.Windows.Forms.ColorPicker/HslColor.cs

dont know about license though. Hope u like it!

JG in SD
  • 5,427
  • 3
  • 34
  • 46
user3305711
  • 441
  • 5
  • 16
  • I think this is a good idea to use "invoke". Could we adjust Alpha channel in RGBA color instead of HSL? – Buzz Oct 12 '15 at 21:56
1

Here's what I wrote. It also handles labels of different colors (e.g. green, red)

Instance the class, attach to the label any time. After you set the message and the initial foreground color, then call setColorSteps and how many steps you want.

When you want to run the fade, call doFade()

Props to OP for the timer loop event, which I used when I wrote this solution that worked for what I needed.

/// <summary>
/// Fade a label - Derek Piper 2019
/// </summary>
public class LabelFader
{
    Label label;
    List<ColorStep> colorSteps = new List<ColorStep>();

    public void attachToControl(Label useLabel)
    {
        this.label = useLabel;
    }

    public void setColorSteps(int numSteps)
    {
        if (this.label != null)
        {
            ColorStep start = new ColorStep(this.label.ForeColor);
            ColorStep end = new ColorStep(this.label.BackColor);
            int redIncrement = ((end.R - start.R) / numSteps);
            int greenIncrement = ((end.G - start.G) / numSteps);
            int blueIncrement = ((end.B - start.B) / numSteps);
            this.colorSteps = new List<ColorStep>();
            for (int i = 0; i <= numSteps; i++)
            {
                ColorStep newStep = new ColorStep();
                if (redIncrement > 0)
                {
                    newStep.R = start.R + (i * redIncrement);
                }
                else
                {
                    newStep.R = start.R - (i * redIncrement);
                }
                if (greenIncrement > 0)
                {
                    newStep.G = start.G + (i * greenIncrement);
                }
                else
                {
                    newStep.G = start.G - (i * greenIncrement);
                }
                if (blueIncrement > 0)
                {
                    newStep.B = start.B + (i * blueIncrement);
                }
                else
                {
                    newStep.B = start.B - (i * blueIncrement);
                }
                this.colorSteps.Add(newStep);
            }
        }
    }

    public void doFade(int speedMs = 40)
    {
        Timer tm = new Timer();
        tm.Interval = speedMs;
        int step = 0;
        int end = this.colorSteps.Count;
        if (this.colorSteps.Count > 0)
        {
            tm.Tick += (sa, aea) =>
            {
                ColorStep thisStep = this.colorSteps[step];
                this.label.ForeColor = Color.FromArgb(thisStep.R, thisStep.G, thisStep.B);
                step++;
                if (step >= end)
                {
                    tm.Stop();
                    this.label.Visible = false;
                }
            };
            tm.Start();
        }
    }
}

class ColorStep
{
    public int R = 0;
    public int G = 0;
    public int B = 0;

    public ColorStep()
    {
    }

    public ColorStep(Color from)
    {
        this.setFromColor(from);
    }

    public void setFromColor(Color from)
    {
        this.R = from.R;
        this.G = from.G;
        this.B = from.B;
    }

    public Color getColor()
    {
        return Color.FromArgb(this.R, this.G, this.B);
    }
}
Delphis
  • 11
  • 1