maui

How to produce a "flashing" UI element in Maui


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).


Solution

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