I have a simple blazor site using Mudblazor. My mainlayout is simple so that it has the mudblazor theme provider, it also has an app bar and a side bar which are there own components. I want to be able to switch between dark and light mode which i have done successfully by following the guidance on the Mudblazor site.
What i want to do now is move the MudSwitch to the AppBar so its always available.
I have tried, cascadingparameters and event calls backs but neither of them worked in their entirety, i could get values set and events called but i could never get theme change.
Can someone please assist me with what the correct approach is and how it can be done.
MainLayout.razor
@using demo.UI.Components
@inherits LayoutComponentBase
<MudThemeProvider @bind-IsDarkMode="@_isDarkMode" Theme="_theme" />
<MudLayout>
<AppBar />
<SideBar />
<MudMainContent>
@*Body*@
this is my content, blah blah
<MudSwitch @bind-Value="@_isDarkMode" Color="Color.Primary" Class="ma-4" T="bool" Label="Toggle Light/Dark Mode" />
</MudMainContent>
</MudLayout>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
@code
{
private MudTheme _theme = new();
private bool _isDarkMode = true;
}
AppBar.razor
<MudAppBar Elevation="1" Dense="true">
<NavLink href="/">
home
</NavLink>
<MudSpacer />
<i class="fa-solid fa-right-to-bracket" style="color: #059669;"></i>
</MudAppBar>
I'd recommend you to handle the theme change in the MainLayout component and not other components.
Since you have MudAppBar in your own AppBar component, then the simplest way is to use two way binding using Parameter & EventCallback.
The child component AppBar will notify the parent component MainLayout whenever the dark/light mode switch is toggled. Then the parent component will change the MudThemeProvider's IsDarkMode property.
Here's a demo of the code below. MudBlazor Snippet Demo
<MudAppBar Elevation="1" Dense="true">
<NavLink href="/" >
home
</NavLink>
<MudSpacer />
<MudSwitch Value="@IsDarkModeToggle" ValueChanged="HandleToggleChanged" Color="Color.Primary" Class="ma-4" T="bool" Label="Toggle Light/Dark Mode" />
<i class="fa-solid fa-right-to-bracket" style="color: #059669;"></i>
</MudAppBar>
@code{
[Parameter] public bool IsDarkModeToggle {get;set;}
[Parameter] public EventCallback<bool> IsDarkModeToggleChanged { get; set; }
async Task HandleToggleChanged(bool newToggleValue)
{
await IsDarkModeToggleChanged.InvokeAsync(newToggleValue);
}
}
In the example for the AppBar above I use Value and ValueChanged instead of a @bind as I need to perform custom logic when the value is changed.
If you've configured the Parameters correctly and followed the naming convention of Blazor parameters i.e. MyParameter & MyParameterChanged and you don't need to perform other actions in the parent component then, you can directly @bind it to the same field that the MudThemeProvider is bound to. i.e. _isDarkMode. Now if anything changes the MudThemeProvider's IsDarkMode, it will change the toggle correctly aswell.
@page "/__main"
<MudThemeProvider @bind-IsDarkMode="@_isDarkMode" Theme="_theme" />
<MudLayout>
<AppBar @bind-IsDarkModeToggle="_isDarkMode"/>
<MudDrawer @bind-Open="@open" Breakpoint="@breakpoint" Elevation="1" Variant="@DrawerVariant.Responsive" PreserveOpenState="@preserveOpenState">
<MudDrawerHeader>
<MudText Typo="Typo.h6">My App</MudText>
</MudDrawerHeader>
<MudNavMenu>
<MudNavLink Match="NavLinkMatch.All">Store</MudNavLink>
<MudNavLink Match="NavLinkMatch.All">Library</MudNavLink>
<MudNavLink Match="NavLinkMatch.All">Community</MudNavLink>
</MudNavMenu>
</MudDrawer>
<MudMainContent Class="pt-16 px-16">
<MudContainer Class="mt-6">
@*Body*@
this is my content, blah blah
</MudContainer>
</MudMainContent>
</MudLayout>
@code{
private MudTheme _theme = new();
private bool _isDarkMode = true;
bool open = false;
bool preserveOpenState = false;
Breakpoint breakpoint = Breakpoint.Lg;
void ToggleDrawer()
{
open = !open;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With