How to implement a blinking label on a form
Asked Answered
I

8

20

I have a form that displays queue of messages and number this messages can be changed. Really I want to blink label (queue length) when the number of messages were increased to improve form usability. Should I implement custom control and use additional thread or timer to change color of label? Has anybody implemented so functionality? What is the best solution (less resources and less performance degradation) to implement so behaviour?

SOLUTION:

Form's component with timer that can restrict number of animations per second and implement fade out effect to external control background color.

Ikeda answered 18/2, 2011 at 14:32 Comment(7)
<blink>I hate blinking text and never forgave Netscape</blink>Annia
@David: blinking is better than the marquee nonsense, at least. I have coworkers who are desperately trying to re-introduce the marquee to iPhone/iPad apps - they were not alive in the 90's, as far as I can tell.Sunk
@David Heffernan alternative?Ikeda
@Igor alternative is not to blink!Annia
@David Heffernan how can form attract user attention? Or maybe it's useless feature?Ikeda
@igor I don't know your app but I know I hate blinkingAnnia
Blinking text was pivotal in the success of a prank I pulled on a co-worker. The impact would have been significantly reduced if I didn't have access to this technology.Unvarnished
G
3

You can create a custom component and events to start blinking --which I think is a good solution. The Blinking you can implement with a timer.

Genipap answered 18/2, 2011 at 14:35 Comment(0)
H
34

The following is blinking using async and await

private async void Blink(){
    while (true){
        await Task.Delay(500);
        label1.BackColor = label1.BackColor == Color.Red ? Color.Green : Color.Red;
    }
}
Hagiolatry answered 18/3, 2015 at 8:46 Comment(2)
What's your approach killing this process?Chau
you can add a check for a bool var inside the loop _continueBlink and check while it's true continue, else leave the loop, you can then set it to false somewhere else to leave blinking loopHagiolatry
G
30

I know this is a really old post, but anyone looking for something a little more versatile than the Boolean solutions posted may get some use out of the following: enter image description here

using System.Diagnostics;
using System.Threading.Tasks;

private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
{
    var sw = new Stopwatch(); sw.Start();
    short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
    while (true)
    {
        await Task.Delay(1);
        var n = sw.ElapsedMilliseconds % CycleTime_ms;
        var per = (double)Math.Abs(n - halfCycle) / halfCycle;
        var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R;
        var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G;
        var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B;
        var clr = Color.FromArgb(red, grn, blw);
        if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
    }
}

Which you can call like such:

SoftBlink(lblWarning, Color.FromArgb(30, 30, 30), Color.Red,2000,false);
SoftBlink(lblSoftBlink, Color.FromArgb(30, 30, 30), Color.Green, 2000,true);
Guacharo answered 9/6, 2017 at 22:9 Comment(4)
This has been my preferred solution.Devotee
Could you provide this example for NET 1.1? I would like to put it in a legacy project. Also is this working for any foreground and backgound color?Syllabus
I use NET 3.5, and instead of async/await this solution https://mcmap.net/q/279117/-wait-some-seconds-without-blocking-ui-execution but it's not working very wellStinkhorn
No I got it ! It works with WaitNMilliseconds(), not WaitNSeconds().Stinkhorn
G
14
Timer timer = new Timer();
timer.Interval = 500;
timer.Enabled = false;

timer.Start();

if( messagesNum > oldMessagesNum)
  timer.Tick += new EventHandler( timer_Tick );
else
  timer.Tick -= timer_Tick;

void timer_Tick( object sender, EventArgs e )
{
   if(messageLabel.BackColor == Color.Black)
      messageLabel.BackColor = Color.Red;
   else
      messageLabel.BackColor = Color.Black;
}

Here is a pretty simple implementation that would work inside your form. You could also create a custom control with the same code and just throw the Timer.Start() into a method for that control.

Gilolo answered 18/2, 2011 at 15:4 Comment(0)
S
5

Create your own UserControl for this, one that inherits from Label instead of from Control directly. Add a StartBlinking method, in which you start a Timer object whose tick event alters the style of the label (changing the BackgroundColor and ForegroundColor properties each time to create the blink effect).

You could also add a StopBlinking method to turn it off, or you could have your Timer stop itself after 5 seconds, perhaps.

Sunk answered 18/2, 2011 at 14:40 Comment(0)
G
3

You can create a custom component and events to start blinking --which I think is a good solution. The Blinking you can implement with a timer.

Genipap answered 18/2, 2011 at 14:35 Comment(0)
L
3

Can you use an animated .gif instead (perhaps as the background of the number)? it would make it look like old school web pages, but it might work.

Liquidate answered 18/2, 2011 at 14:38 Comment(4)
-1 because downvotes are a good way to learn to avoid grisly hacks. :)Sunk
@Sunk that's personal opinion :PLiquidate
Share by multiple people, hacks are hacks, and should only be used as a last resort.Terrific
@Ramhoud I'm guessing you didn't understand what I said. I was arguing that my solution was not a hack. It correctly solves the problem of "bringing attention to this part of the screen".Liquidate
Z
0

You can use Timer class here. Here what I have implemented. Label color blinking on Button_click Event.

//click event on the button to change the color of the label
public void buttonColor_Click(object sender, EventArgs e)
        {
            Timer timer = new Timer();
            timer.Interval = 500;// Timer with 500 milliseconds
            timer.Enabled = false;

            timer.Start();

            timer.Tick += new EventHandler(timer_Tick);
        }

       void timer_Tick(object sender, EventArgs e)
    {
        //label text changes from 'Not Connected' to 'Verifying'
        if (labelFirst.BackColor == Color.Red)
        {
            labelFirst.BackColor = Color.Green;
            labelFirst.Text = "Verifying";
        }

        //label text changes from 'Verifying' to 'Connected'
        else if (labelFirst.BackColor == Color.Green)
        {
            labelFirst.BackColor = Color.Green;
            labelFirst.Text = "Connected";
        }

        //initial Condition (will execute)
        else
        {
            labelFirst.BackColor = Color.Red;
            labelFirst.Text = "Not Connected";
        }
    }
Zephyr answered 20/8, 2018 at 11:59 Comment(0)
B
0

this is how i ended up doing it

public partial class MemberDisplay : Form
{
    public string Input;
    public int MASS_STOP = 1;

    public MemberDisplay(string msg)
    {
        InitializeComponent();
        State_Entry();
        Input = msg;
    }

    public void State_Entry()
    {
        this.SpecialFocus.Select();
        this.lbl_TimerTest.Hide();
    }

    private async void RunBlinkyTest(string msg)
    {
        while (msg == "GO" && (MASS_STOP == 0))
        {
            await Task.Delay(500);
            
            lbl_TimerTest.ForeColor =
                lbl_TimerTest.ForeColor == Color.Red ?
                    Color.Black :
                    Color.Red;

            if (msg == "STOP" && (MASS_STOP == 1)) { return; }
        }
    }

    private void btn_TimeTest_Click(object sender, EventArgs e)
    {
        if (btn_TimeTest.Text == "GO")
        {
            this.lbl_TimerTest.Show();
            MASS_STOP = 0;
            RunBlinkyTest("GO");
            btn_TimeTest.Text = "STOP";
            return;
        }

        if (btn_TimeTest.Text == "STOP")
        {
            MASS_STOP = 1;
            RunBlinkyTest("STOP");
            this.lbl_TimerTest.ForeColor = Color.Black;
            this.lbl_TimerTest.Hide();
            btn_TimeTest.Text = "GO";
            return;
        }
    }
}
Benjaminbenji answered 18/1, 2023 at 6:10 Comment(1)
Please add some explanation to your code. Right now nobody can learn of your answer and just copy & paste some unknown code to their application. And please watch the code formatting :)Einberger

© 2022 - 2024 — McMap. All rights reserved.