Search code examples
c#labelbackcolor

blinking labels backColor in C#


I have this Form containing 4 labels. I want these labels to blink with a specified frequency, like 12.5, 10, 8 and 4 HZ. I used a Timer, but it won't work correctly, They blink with much lower frequency, I know it's because nested ifs in the freqMethod below. How should I solve this issue?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Timers;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        System.Timers.Timer mainTimer; 
        private int counter = 0;
        Color lColor = Color.FromArgb(255, 192, 128);
        bool buttonPressed = false;

        public Form1()
        {

            InitializeComponent();
            label1.BackColor = lColor;
            label2.BackColor = lColor;
            label3.BackColor = lColor;
            label4.BackColor = lColor;
            mainTimer = new System.Timers.Timer(1);
            mainTimer.Elapsed += new ElapsedEventHandler(timerElapsed);
        }


        private void button2_Click(object sender, EventArgs e)
        {   
            if (buttonPressed)
            {
                mainTimer.Enabled = false;
                buttonPressed = !buttonPressed;
                counter = 0;
            }
            else
            {

                mainTimer.Enabled = true;
                buttonPressed = !buttonPressed;
                counter = 0;
            }
        }

        //Frequency Method

        public void freqMethod()
        {
           if (counter % 80 == 0)
               if (label4.backColor == lColor)
                   label4.backColor = Color.black;
               else
                   label4.backColor = lColor;
           if (counter % 100 == 0)
               if (label3.backColor == lColor)
                   label3.backColor = Color.black;
               else
                   label3.backColor = lColor;
           if (counter % 125 == 0)
               if (label2.backColor == lColor)
                   label2.backColor = Color.black;
               else
                   label2.backColor = lColor;
           if (counter % 250 == 0)
               if (label1.backColor == lColor)
                   label1.backColor = Color.black;
               else
                   label1.backColor = lColor;



        }
        private void timerElapsed(object source, ElapsedEventArgs e) {
            counter++;
            freqMethod();
        }

    }
}

Solution

  • You don't need timer to iterate every second as you skip it's every n iterations while they take too much resources. You can just manipulate with Timer's Interval value to get the required frequency with adeqate performance.

    For example, for frequency 8 Hz you only need timer to fire an event every 125 ms (8 times per second).
    I will provide an example with a double frequency in order to make it work with intervals < 1. For example, if you set frequency to 0.5, the color will change every 2 seconds.

    Example:

    public Form1()
    {
        double frequencyInHz = 8.0; // here goes your frequency
        int interval = (int)Math.Round(1000.0 / frequencyInHz); // 125ms in this case
        mainTimer = new Timer(interval);
        mainTimer.Elapsed += new ElapsedEventHandler(timerElapsed);
    }   
    
    private void timerElapsed(object source, ElapsedEventArgs e) {
        if (label2.BackColor == lColor)
            label2.BackColor = Color.Black;
        else
            label2.BackColor = lColor;
    }
    

    If you need several labels to change their colors with different, you will need to make several timers in order to get a good performance.