Reputation: 89
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
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