Ako
Ako

Reputation: 1581

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();
        }

    }
}

Upvotes: 1

Views: 1937

Answers (3)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34234

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.

Upvotes: 1

Joel Legaspi Enriquez
Joel Legaspi Enriquez

Reputation: 1236

Given the following values (and if you want to synchronized them using one timer) the common interval they can have is 5ms. So you need to tick the timer 5ms each and check the frequency. But take note on using the timer as explained below:

12.5hz = 80ms
10hz   = 100ms
8hz    = 125ms
4hz    = 250ms

Remarks from MSDN using System.Timers.Timer (https://msdn.microsoft.com/en-us/library/system.timers.timer.interval(v=vs.110).aspx) See remarks section.

You use the Interval property to determine the frequency at which the Elapsed event is fired. Because the Timer class depends on the system clock, it has the same resolution as the system clock. This means that the Elapsed event will fire at an interval defined by the resolution of the system clock if the Interval property is less than the resolution of the system clock. The following example sets the Interval property to 5 milliseconds. When run on a Windows 7 system whose system clock has a resolution of approximately 15 milliseconds, the event fires approximately every 15 milliseconds rather than every 5 milliseconds

But if you can use multiple timer for each, then you can set each interval of the timer as Yeldar mentioned.

Upvotes: 2

Graffito
Graffito

Reputation: 1718

Try this (in addition to the timer interval modification proposed by Joel or Yeldar) :

if (counter % 80 == 0)
{
  label4.backColor = label4.backColor == lColor ? Color.black : lColor;
  label4.Refresh() ;
}

Upvotes: 1

Related Questions