Skip to content
Shiny Controls v1.0 - The Ultra Control Suite for .NET MAUI & BlazorO...M...G!

Overlay & LoadingOverlay

A full-screen overlay control with backdrop dimming, optional frosted glass blur, and fade animation. On MAUI, integrates with OverlayHost/ShinyContentPage (the same backdrop system used by FloatingPanel). The base Overlay supports any custom content via DataTemplate (MAUI) or RenderFragment (Blazor). The LoadingOverlay subclass provides a built-in loading template with either an indeterminate spinner or a determinate progress bar.

  • NuGet downloads for Shiny.Maui.Controls
  • NuGet downloads for Shiny.Blazor.Controls
Frameworks
.NET MAUI
Blazor

MAUI

Custom Overlay Loading Spinner Loading Progress

Blazor

Custom overlay Loading spinner Determinate progress
Custom overlay on Blazor Loading spinner on Blazor Determinate progress on Blazor
  • Integrates with OverlayHost/ShinyContentPage on MAUI (shared backdrop with FloatingPanel)
  • Optional frosted glass blur effect behind the backdrop
  • Smooth fade in/out animation
  • Custom content support via DataTemplate (MAUI) or RenderFragment (Blazor)
  • Built-in LoadingOverlay with spinner or progress bar
  • Two-way bindable IsShown property
  • Backdrop tap to dismiss
  • Optional message text

Overlays must be placed inside ShinyContentPage.Panels (or an OverlayHost). The page must use ShinyContentPage as its base class.

<shiny:ShinyContentPage xmlns:shiny="http://shiny.net/maui/controls" ...>
<!-- Page content (set via ContentProperty) -->
<ScrollView>
<VerticalStackLayout Padding="16">
<Button Text="Show Overlay" Command="{Binding ShowOverlayCommand}" />
</VerticalStackLayout>
</ScrollView>
<!-- Overlays in the Panels collection -->
<shiny:ShinyContentPage.Panels>
<shiny:Overlay IsShown="{Binding IsOverlayVisible}"
BlurRadius="10">
<shiny:Overlay.OverlayContentTemplate>
<DataTemplate>
<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center" Spacing="12">
<Label Text="Hello from the overlay!" TextColor="White" FontSize="20" />
<Button Text="Dismiss" Command="{Binding DismissCommand}" />
</VerticalStackLayout>
</DataTemplate>
</shiny:Overlay.OverlayContentTemplate>
</shiny:Overlay>
</shiny:ShinyContentPage.Panels>
</shiny:ShinyContentPage>
<shiny:ShinyContentPage.Panels>
<shiny:LoadingOverlay IsShown="{Binding IsBusy}"
Message="Loading, please wait..." />
</shiny:ShinyContentPage.Panels>
<shiny:ShinyContentPage.Panels>
<shiny:LoadingOverlay IsShown="{Binding IsBusy}"
IsIndeterminate="False"
Progress="{Binding DownloadProgress}"
Message="Downloading..." />
</shiny:ShinyContentPage.Panels>

Every ShinyContentPage has a LoadingOverlay built in — no need to add one to Panels. Bind IsLoading and it shows on top of everything (it never dismisses on a backdrop tap). Customize with the Loading* passthrough properties, including a LoadingContentTemplate that replaces the spinner content entirely.

<shiny:ShinyContentPage IsLoading="{Binding IsBusy}"
LoadingMessage="Working on it…"
LoadingBlurRadius="8"
...>
<ScrollView>...</ScrollView>
<!-- optional: fully custom loading content -->
<shiny:ShinyContentPage.LoadingContentTemplate>
<DataTemplate>
<Label Text="Please wait…" TextColor="White"
HorizontalOptions="Center" VerticalOptions="Center" />
</DataTemplate>
</shiny:ShinyContentPage.LoadingContentTemplate>
</shiny:ShinyContentPage>

Passthroughs: IsLoading, LoadingMessage, LoadingIsIndeterminate, LoadingProgress, LoadingSpinnerColor, LoadingBlurRadius, LoadingContentTemplate, and the underlying LoadingOverlay instance. The base Overlay also has CloseOnBackdropTap (default true) to opt out of tap-to-dismiss.

<Overlay IsShown="@isShown" OverlayColor="rgba(0, 0, 0, 0.6)" BlurRadius="10">
<ChildContent>
<button @onclick="() => isShown = true">Show Overlay</button>
</ChildContent>
<OverlayContent>
<div style="color: white; text-align: center;">
<h2>Hello from the overlay!</h2>
<button @onclick="() => isShown = false">Dismiss</button>
</div>
</OverlayContent>
</Overlay>
<LoadingOverlay IsShown="@isBusy"
IsIndeterminate="false"
Progress="@progress"
BlurRadius="8"
Message="Downloading...">
<p>Page content that gets overlaid when loading</p>
</LoadingOverlay>
Property Type Default Description
IsShown bool false Show/hide the overlay (TwoWay)
AnimationDuration uint 250 Fade animation duration in ms
BlurRadius double 0 When > 0, applies a frosted glass blur effect behind the backdrop using FrostedGlassView. Uses native platform blur (UIVisualEffectView on iOS, RenderEffect on Android 12+).
OverlayContentTemplate DataTemplate null Custom overlay content

Backdrop color and opacity are controlled at the ShinyContentPage / OverlayHost level:

Property Type Default Description
BackdropColor Color Black Shared backdrop color
BackdropMaxOpacity double 0.5 Maximum backdrop opacity when shown
Parameter Type Default Description
IsShown bool false Show/hide overlay
IsShownChanged EventCallback<bool> Two-way binding callback
OverlayColor string “rgba(0,0,0,0.5)” CSS color for backdrop
OverlayOpacity double 1.0 Additional opacity multiplier
BlurRadius double 0 When > 0, applies CSS backdrop-filter: blur(Xpx) to the backdrop
ChildContent RenderFragment Normal page content
OverlayContent RenderFragment Content rendered in the overlay
CssClass string? null Additional CSS class

Inherits all Overlay properties, plus:

Property Type Default Description
IsIndeterminate bool true true = spinner, false = progress bar
Progress double 0 Progress 0–100 (TwoWay)
Message string? null Text below the loading indicator
SpinnerColor Color White ActivityIndicator color
Parameter Type Default Description
IsIndeterminate bool true Spinner (true) or progress bar (false)
Progress double 0 Progress 0–100
Message string? null Text below the loading indicator
SpinnerColor string “#FFFFFF” CSS spinner border color
SpinnerSize double 48 Spinner diameter in px
ProgressBarColor string “#FFFFFF” Progress bar fill color
ProgressTrackColor string “rgba(255,255,255,0.2)” Progress bar track color
BlurRadius double 0 When > 0, applies CSS backdrop-filter: blur(Xpx) to the backdrop

MAUI: Place Overlay or LoadingOverlay inside ShinyContentPage.Panels or an OverlayHost. They share the backdrop with FloatingPanel — only one backdrop is shown at a time, and it auto-hides when all clients dismiss. Tapping the backdrop dismisses the overlay.

Blazor: The Overlay component uses ChildContent for your normal page content and OverlayContent for what appears in the overlay. Uses fixed CSS positioning when shown. No ShinyContentPage equivalent needed.

Your page must inherit from ShinyContentPage:

using Shiny.Maui.Controls;
public partial class MyPage : ShinyContentPage
{
public MyPage()
{
InitializeComponent();
}
}

Overlay centres its content, which is right for a dialog and wrong for a prompt bar. ContentAlignment (Start / Center / End) and ContentMargin move it — that is how the Quick Entry popup sits in the upper third of the page while sharing this control’s backdrop, blur and show/hide worker rather than reimplementing them.

ShowEdgeGlow rims the page with an animated Siri-style colour wash for as long as the overlay is up, sequenced with its own show and hide. It sits behind the content and in front of the backdrop, and is click-through, so it is purely a signal that something is happening. GlowOptions (a ScreenGlowOptions) tunes thickness, palette, speed, pulse and intensity; leave it null for the defaults.

<shiny:Overlay IsShown="{Binding IsAsking}"
ContentAlignment="Start"
ContentMargin="0,120,0,0"
ShowEdgeGlow="True"
BlurRadius="18" />

A DataTemplate that returns the same view instance each time is supported, which is how you host one long-lived view rather than rebuilding it on every show.