.net.net-coredispatcherbegininvokeblazor

Blazor .Net + Dispatcher.BeginInvoke( )?


Is it possible to do the following using the new Blazor framework?

I have a page that displayed a list of people. The list is essentially a bindable list of Person objects.

Desired Result I would like to show each person fade-in independently of each other.

For example: The 1st row starts fading in first. The Nth row person will be the last to fade in.

What I tried I've tried a couple of things using Task.Delay() and tried to get Dispatcher.BeginInvoke() to work.

But now i am starting to think this is not possible without doing some kind of hack.

Is this kind of effect even possible via Blazor? Is there a Dispatcher.BeginInvoke() equivalent?


Solution

  • One option, if your Blazor application is run on client-side, is to use a combination of CSS3 animations to fade in rows and a Task.Delay to add rows delayed.

    I will give you an example based on the default Blazor (.NET core 3.0 preview 3) template.

    Inspired by this SO answer you could add the following CSS class to your site.css or some costom CSS file:

    .fadein {
        -webkit-animation: fadein 1s; /* Safari, Chrome and Opera > 12.1 */
        -moz-animation: fadein 1s; /* Firefox < 16 */
        -ms-animation: fadein 1s; /* Internet Explorer */
        -o-animation: fadein 1s; /* Opera < 12.1 */
        animation: fadein 1s;
    }
    
    @keyframes fadein {
        from {
            opacity: 0;
        }
    
        to {
            opacity: 1;
        }
    }
    
    /* Firefox < 16 */
    @-moz-keyframes fadein {
        from {
            opacity: 0;
        }
    
        to {
            opacity: 1;
        }
    }
    
    /* Safari, Chrome and Opera > 12.1 */
    @-webkit-keyframes fadein {
        from {
            opacity: 0;
        }
    
        to {
            opacity: 1;
        }
    }
    
    /* Internet Explorer */
    @-ms-keyframes fadein {
        from {
            opacity: 0;
        }
    
        to {
            opacity: 1;
        }
    }
    

    Now we will modify the FetchData.razor page, which by default shows a HTML table with some forecast info.

    First we add a style class to the table rows <tr> as following:

    @foreach (var forecast in forecasts)
    {
        <tr class="fadein">
            <td>@forecast.Date.ToShortDateString()</td>
            <td>@forecast.TemperatureC</td>
            <td>@forecast.TemperatureF</td>
            <td>@forecast.Summary</td>
        </tr>
    }
    

    Next we will change the type of the forecasts from an array to a List:

    List<WeatherForecast> forecasts = new List<WeatherForecast>();
    

    As a last step we replace the forecasts preparation in the OnInitAsync with the following call:

    protected override async Task OnInitAsync()
    {
        await FadeInItems();
    }
    

    and add the method for the delayed fading in:

    private async Task FadeInItems()
    {
        var items = await Http.GetJsonAsync<WeatherForecast[]>("sample-data/weather.json");
    
        // don't forget to use the desired sorting / filtering on your collection
        foreach (var item in items)
        {
            forecasts.Add(item);
            base.StateHasChanged();
            await Task.Delay(500);
        }
    }
    

    And this should be your result: fade in animation

    Based on this demo, you should now be able to apply this method to your Person model and individual razor page(s). Ofcourse the animation, delay and other things are just an example and can be customized.