I have a working solution in WinForms and Xamarin which I am now trying to re-implement in Maui. I'm trying to make a UI element "flash" by changing color from black to red and back again, repeating.
The issue is that the code appears to function, but the UI does not change - the "flashing" UI element just sits there unchanging.
I want to "flash" the UI element at different rates - as you can see here (times are in milliseconds):
switch (flashRate)
{
case FlashRate.Flashing:
lighton.Interval = 200;
heartbeat.Interval = 1200;
break;
case FlashRate.LongFlash:
lighton.Interval = 2000;
heartbeat.Interval = 4200;
break;
case FlashRate.Quick:
lighton.Interval = 200;
heartbeat.Interval = 975;
break;
case FlashRate.VeryQuick:
lighton.Interval = 200;
heartbeat.Interval = 562;
break;
case FlashRate.UltraQuick:
lighton.Interval = 200;
heartbeat.Interval = 370;
break;
}
The approach I have used so far is to use two timers:
Whenever the heat-beat event fires, the UI element's color is set to Red, and the Light-On timer activated.
Whenever the Light-On event fires, the UI element's color is set to black.
private void Lighton_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
brdLightsim.BackgroundColor = Color.FromRgb(0, 0, 0);
}
private void heartbeat_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
brdLightsim.BackgroundColor = Color.FromRgb(255, 0, 0);
lighton.Start();
}
The border is defined thus:
<Border
x:Name="brdLightsim"
Stroke="Gray"
StrokeThickness="3"
StrokeShape="RoundRectangle 10,10,10,10"
Padding="30"
HorizontalOptions="Center">
<Label x:Name="lblLight" Text="[Light]"
TextColor="White"
FontSize="18"
Margin="20"
FontAttributes="Bold" />
</Border>
The two timer events are definitely firing (breakpoints are hit).
I can use brdLightsim.BackgroundColor = Colors.Blue;
to set the color successfully on a button click (that also starts the heat-beat, etc).
Could it be an issue with threads?
The button works because it's all on UI thread. I assume the flashing happens using some sort of timer on a background thread. UI work needs to be done on an UI thread like so:
MainThread.BeginInvokeOnMainThread(() =>
{
brdLightsim.BackgroundColor = Color.FromRgb(0, 0, 0);
});