Services

MudBlazor provides several useful services.

BrowserViewportService

Provides functionality to get the current view port size, to monitor the browser viewport size for any changes and to get the current breakpoint.

Lambda-implementation

Browser width: 0 px

Browser height: 0 px

@using MudBlazor.Services
@inject IBrowserViewportService BrowserViewportService
@implements IAsyncDisposable

<MudStack Spacing="2">
    <MudText>Browser width: @_currentBrowserWindowSize.Width px</MudText>
    <MudText>Browser height: @_currentBrowserWindowSize.Height px</MudText>
</MudStack>
@code {
    private readonly Guid _observerId = Guid.NewGuid();
    private BrowserWindowSize _currentBrowserWindowSize = new();

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            await BrowserViewportService.SubscribeAsync(_observerId, args =>
            {
                _currentBrowserWindowSize = args.BrowserWindowSize;
                StateHasChanged();
            });
        }
    }

    public async ValueTask DisposeAsync()
    {
        await BrowserViewportService.UnsubscribeAsync(_observerId);
    }
}
Interface-implementation

This requires to inherit from IBrowserViewportObserver .

Browser width: 0 px

Browser height: 0 px

@using MudBlazor.Services
@inject IBrowserViewportService BrowserViewportService
@implements IBrowserViewportObserver
@implements IAsyncDisposable

<MudStack Spacing="2">
    <MudText>Browser width: @_currentBrowserWindowSize.Width px</MudText>
    <MudText>Browser height: @_currentBrowserWindowSize.Height px</MudText>
</MudStack>
@code {
    public Guid Id { get; } = Guid.NewGuid(); // The id of the observer
    public ResizeOptions ResizeOptions { get; } = new() // The observer options
    {
        NotifyOnBreakpointOnly = false
    };

    private BrowserWindowSize _currentBrowserWindowSize = new();

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            await BrowserViewportService.SubscribeAsync(this, fireImmediately: true);
        }
    }

    public async ValueTask DisposeAsync()
    {
        await BrowserViewportService.UnsubscribeAsync(this);
    }

    public Task NotifyBrowserViewportChangeAsync(BrowserViewportEventArgs browserViewportEventArgs)
    {
        _currentBrowserWindowSize = browserViewportEventArgs.BrowserWindowSize;
        return InvokeAsync(StateHasChanged);
    }
}
ResizeObserver

The ResizeObserver is similar to BrowserViewportService but for elements instead of the browser window.

Don't inject the IResizeObserver directly. Always use the IResizeObserverFactory instead.

This div is 0 px wide

@using MudBlazor.Interop
@using MudBlazor.Services
@inject IResizeObserverFactory ResizeObserverFactory
@implements IAsyncDisposable

<div @ref="_divReference" style="width: 100%; text-align: center;">
    <MudText>This div is @_divWidth px wide</MudText>
</div>
@code {
    private IResizeObserver _resizeObserver;
    private ElementReference _divReference;
    private double _divWidth;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            _resizeObserver = ResizeObserverFactory.Create();
            _resizeObserver.OnResized += ResizeObserverOnResized;
            await _resizeObserver.Observe(_divReference);
            _divWidth = _resizeObserver.GetWidth(_divReference);
            StateHasChanged();
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (_resizeObserver != null) await _resizeObserver.DisposeAsync();
    }

    private void ResizeObserverOnResized(IDictionary<ElementReference, BoundingClientRect> changes)
    {
        _divWidth = changes.Values.LastOrDefault()?.Width ?? 0;
        StateHasChanged();
    }
}
ScrollManager

This service provides general scroll functionality for scrolling.

@inject IScrollManager ScrollManager

<MudStack Row="true">
    <MudButton OnClick="@ToggleScrollLockAsync" Variant="Variant.Filled" EndIcon="@LockScrollBtIcon">@LockScrollBtText</MudButton>
    <MudButton OnClick="@(() => ScrollManager.ScrollIntoViewAsync("#iresizeobserver", ScrollBehavior.Smooth))" Variant="Variant.Filled">Scroll to resize observer</MudButton>
</MudStack>
@code {
    private bool _scrollIsLocked;
    private string LockScrollBtText => _scrollIsLocked ? "Unlock scroll" : "Lock scroll";
    private string LockScrollBtIcon => _scrollIsLocked ? Icons.Material.Outlined.LockOpen : Icons.Material.Outlined.Lock;

    private async Task ToggleScrollLockAsync()
    {
        if (_scrollIsLocked) await ScrollManager.UnlockScrollAsync();
        else await ScrollManager.LockScrollAsync();

        _scrollIsLocked = !_scrollIsLocked;
    }
}
ScrollListener

Provides functionality to listen for scroll events for a specific element.

Don't inject the IScrollListener directly. Always use the IScrollListenerFactory instead.

You can attach the scroll listener to any element:

Rectangle scroll position: 0 px

Line 0

Line 1

Line 2

Line 3

Line 4

Line 5

Line 6

Line 7

Line 8

Line 9

Line 10

Line 11

Line 12

Line 13

Line 14

Line 15

Line 16

Line 17

Line 18

Line 19

Line 20

Line 21

Line 22

Line 23

Line 24

Line 25

Line 26

Line 27

Line 28

Line 29

Line 30

Line 31

Line 32

Line 33

Line 34

Line 35

Line 36

Line 37

Line 38

Line 39

Line 40

Line 41

Line 42

Line 43

Line 44

Line 45

Line 46

Line 47

Line 48

Line 49

Line 50

Line 51

Line 52

Line 53

Line 54

Line 55

Line 56

Line 57

Line 58

Line 59

Line 60

Line 61

Line 62

Line 63

Line 64

Line 65

Line 66

Line 67

Line 68

Line 69

Line 70

Line 71

Line 72

Line 73

Line 74

Line 75

Line 76

Line 77

Line 78

Line 79

Line 80

Line 81

Line 82

Line 83

Line 84

Line 85

Line 86

Line 87

Line 88

Line 89

Line 90

Line 91

Line 92

Line 93

Line 94

Line 95

Line 96

Line 97

Line 98

Line 99

@inject IScrollListenerFactory ScrollListenerFactory
@implements IDisposable

<MudStack>
    <MudText>You can attach the scroll listener to any element:</MudText>
    <MudStack>
        <MudText>Rectangle scroll position: @_scrollTopRectangle px</MudText>
        <div id="scroll_div" style="height: 5rem; width: 100%; overflow-y: scroll; scrollbar-width: auto; background-color: rgba(0,0,0,0.5); border-radius: var(--mud-default-borderradius);">
            <MudStack Spacing="0" Style="color: var(--mud-palette-text-primary); background-color: var(--mud-palette-background);" Class="pa-4">
                @for (var i = 0; i < 100; i++)
                {
                    var iLocal = i;
                    <MudText>Line @iLocal</MudText>
                }
            </MudStack>
        </div>
    </MudStack>
</MudStack>
@code {
    private double _scrollTopRectangle;
    private IScrollListener _scrollListenerRect;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
        {
            _scrollListenerRect = ScrollListenerFactory.Create("#scroll_div");
            _scrollListenerRect.OnScroll += ScrollListenerRectOnScroll;
        }
    }

    public void Dispose()
    {
        _scrollListenerRect?.Dispose();
    }

    private void ScrollListenerRectOnScroll(object sender, ScrollEventArgs e)
    {
        _scrollTopRectangle = e.ScrollTop;
        StateHasChanged();
    }
}
An unhandled error has occurred. Reload 🗙