Baiso
Baiso

Reputation: 89

How I can change backColor of a button for a fixed time?

I want to change BackColor of a Button for a fixed time when a certain value comes from a serial port. I set the Timer object here:

public formLabel()
{
    InitializeComponent();
    // ...
    timerColor.Tick += timerColor_Tick;
    timerColor.Interval = 3000;
}

Then, when I receive signal from a serial port:

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    MessageBox.Show("Dati Ricevuti: " + indata);
    if (indata.CompareTo("K") == 0)
    {
        timerColor.Enabled = true;
        btnEsito.BackColor = Color.Green;
        btnEsito.Text = "GOOD";
        // Do something
    }
    if (indata.CompareTo("O") == 0)
    {
        timerColor.Enabled = true;
        btnEsito.BackColor = Color.Red;
        btnEsito.Text = "NO GOOD";
    }
}

and here is the method to stop the timer:

private void timerColor_Tick(object sender, EventArgs e)
{
    MessageBox.Show("HERE!");
    timerColor.Enabled = false;
    btnEsito.BackColor = Color.White;
}

BackColor of btnEsito becomes Green or Red based on the type of signal I receive but the program doesn't show the message "HERE!", and the button doesn't come back White.

Could anyone help me?

Upvotes: 1

Views: 62

Answers (1)

PaulF
PaulF

Reputation: 6773

The System.Windows.Forms.Timer is designed for single threaded use & needs to be started & stopped on the UI thread. You are trying to start the timer on a separate thread, so you need to ensure modifying the timer Enabled property is done on the UI thread. You could do this by creating a delegate method & invoking that from your event handlers - possibly something like this :

delegate void TimerDelegate(bool Enable);
private void ControlTimer(bool Enable)
{
  timerColor.Enabled = Enable;
}

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    MessageBox.Show("Dati Ricevuti: " + indata);
    if (indata.CompareTo("K") == 0)
    {
        Invoke((TimerDelegate)ControlTimer, true);
        btnEsito.BackColor = Color.Green;
        btnEsito.Text = "GOOD";
        // Do something
    }
    if (indata.CompareTo("O") == 0)
    {
        Invoke((TimerDelegate)ControlTimer, true);
        btnEsito.BackColor = Color.Red;
        btnEsito.Text = "NO GOOD";
    }
}

private void timerColor_Tick(object sender, EventArgs e)
{
    MessageBox.Show("HERE!");
    Invoke((TimerDelegate)ControlTimer, false);
    btnEsito.BackColor = Color.White;
}

Upvotes: 3

Related Questions