@using Microsoft.AspNetCore.WebUtilities;
. . .
. . .
@{
Layout = null;
@*Pass the URL query to select the theme name *@
QueryHelpers.ParseQuery(Request.QueryString.Value).TryGetValue("theme", out var themeName);
themeName = themeName.Count > 0 ? themeName.First() : "bootstrap4";
}
<!DOCTYPE html>
<html lang="en">
<head>
. . .
. . .
@*Sets the selected theme name into styles*@
<link rel='nofollow' href=@("_content/Syncfusion.Blazor/styles/" + themeName + ".css") rel="stylesheet" />
</head>
<body>
. . .
. . .
</body>
</html>
|
@inherits LayoutComponentBase
@inject NavigationManager UrlHelper;
@using Syncfusion.Blazor.DropDowns;
@using Syncfusion.Blazor.Buttons;
@using Microsoft.AspNetCore.WebUtilities
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
<div class="theme-switcher">
@*Theme switcher*@
<SfDropDownList TItem="ThemeDetails" TValue="string" @bind-Value="themeName" DataSource="@Themes">
<DropDownListFieldSettings Text="Text" Value="ID"></DropDownListFieldSettings>
<DropDownListEvents TItem="ThemeDetails" TValue="string" ValueChange="OnThemeChange"></DropDownListEvents>
</SfDropDownList>
</div>
</div>
<div class="content px-4">
@Body
</div>
</div>
</div>
@code {
private string themeName;
public class ThemeDetails
{
public string ID { get; set; }
public string Text { get; set; }
}
@*Theme switcher datasource*@
private List<ThemeDetails> Themes = new List<ThemeDetails>() {
new ThemeDetails(){ ID = "material", Text = "Material" },
new ThemeDetails(){ ID = "bootstrap", Text = "Bootstrap" },
new ThemeDetails(){ ID = "fabric", Text = "Fabric" },
new ThemeDetails(){ ID = "bootstrap4", Text = "Bootstrap 4" },
};
/// <summary>
/// The switcher OnChange event handler.
/// </summary>
public void OnThemeChange(ChangeEventArgs<string, ThemeDetails> args)
{
var theme = GetThemeName();
if (theme != args.ItemData.ID)
{
UrlHelper.NavigateTo(GetUri(args.ItemData.ID), true);
}
}
/// <summary>
/// Returns the theme name from Uri QueryString.
/// </summary>
private string GetThemeName()
{
var uri = UrlHelper.ToAbsoluteUri(UrlHelper.Uri);
QueryHelpers.ParseQuery(uri.Query).TryGetValue("theme", out var theme);
theme = theme.Count > 0 ? theme.First() : "bootstrap4";
return theme;
}
/// <summary>
/// Returns the new Uri to navigate with theme changes.
/// </summary>
private string GetUri(string themeName)
{
var uri = UrlHelper.ToAbsoluteUri(UrlHelper.Uri);
return uri.AbsolutePath + "?theme=" + themeName;
}
protected override void OnInitialized()
{
var theme = GetThemeName();
themeName = theme.Contains("bootstrap4") ? "bootstrap4" : theme;
}
}
|
Good morning,
inspired by the theme switcher above, I am thinking about implementing in Blazor WebAssembly.
Unfortunately, I have to define the stylesheet links in whe wwwroot.index html file - and there is no embedded c# :-(
Can you give me a hint how to implement theme switching in Blazor WebAssembly ??
Regards
Gerhard
<html>
<head>
.....
.....
.....
<link id="theme" rel='nofollow' href="_content/Syncfusion.Blazor/styles/bootstrap4.css" rel="stylesheet" />
</head>
<body>
.....
.....
.....
<script>
function setTheme(theme, isThemeDark) {
getTheme = isThemeDark ? theme + "-dark" : theme;
document.getElementsByTagName('body')[0].style.display = 'none';
let synclink = document.getElementById('theme');
synclink.rel='nofollow' href = '_content/Syncfusion.Blazor/styles/' + theme + '.css';
setTimeout(function () { document.getElementsByTagName('body')[0].style.display = 'block'; }, 200);
}
</script>
</body>
</html> |
@inherits LayoutComponentBase
@inject NavigationManager UrlHelper;
@inject IJSRuntime JSRuntime;
@using Syncfusion.Blazor.DropDowns;
@using Syncfusion.Blazor.Buttons;
@using Microsoft.AspNetCore.WebUtilities;
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
<div class="theme-switcher">
@*Theme switcher*@
<SfDropDownList TItem="ThemeDetails" TValue="string" @bind-Value="themeName" DataSource="@Themes">
<DropDownListFieldSettings Text="Text" Value="ID"></DropDownListFieldSettings>
<DropDownListEvents TItem="ThemeDetails" TValue="string" ValueChange="OnThemeChange"></DropDownListEvents>
</SfDropDownList>
</div>
</div>
<div class="content px-4">
@Body
</div>
</div>
</div>
@code {
private string themeName;
public class ThemeDetails
{
public string ID { get; set; }
public string Text { get; set; }
}
@*Theme switcher datasource*@
private List<ThemeDetails> Themes = new List<ThemeDetails>() {
new ThemeDetails(){ ID = "material", Text = "Material" },
new ThemeDetails(){ ID = "bootstrap", Text = "Bootstrap" },
new ThemeDetails(){ ID = "fabric", Text = "Fabric" },
new ThemeDetails(){ ID = "bootstrap4", Text = "Bootstrap 4" },
};
/// <summary>
/// The switcher OnChange event handler.
/// </summary>
public void OnThemeChange(Syncfusion.Blazor.DropDowns.ChangeEventArgs<string, ThemeDetails> args)
{
JSRuntime.InvokeAsync<object>("setTheme", args.ItemData.ID);
}
/// <summary>
/// Returns the theme name from Uri QueryString.
/// </summary>
private string GetThemeName()
{
var uri = UrlHelper.ToAbsoluteUri(UrlHelper.Uri);
QueryHelpers.ParseQuery(uri.Query).TryGetValue("theme", out var theme);
theme = theme.Count > 0 ? theme.First() : "bootstrap4";
return theme;
}
/// <summary>
/// Returns the new Uri to navigate with theme changes.
/// </summary>
private string GetUri(string themeName)
{
var uri = UrlHelper.ToAbsoluteUri(UrlHelper.Uri);
return uri.AbsolutePath + "?theme=" + themeName;
}
protected override void OnInitialized()
{
var theme = GetThemeName();
themeName = theme.Contains("bootstrap4") ? "bootstrap4" : theme;
}
} |
very interesting.
can anyone share an example code for below link, hopefully it will be available in synfusion..
I Need exact layout in popup format in header (right side) which is available in below link.
We need to switch theme with three option
1.Select type of theme
2.light/dark (given In below link)
2.color selection ( given in below link)
Please help ,it will very useful for all developers who are using syncfusion control
https://www.screencast.com/t/DJS0Xjhne
Note:-
Please add this feature in below source code
https://www.syncfusion.com/forums/153610/side-bar-height-not-100
Thanks for support ...
Please add this option in popup dropdown
Which I mention in attached video and also add color option in poupup
Sorry no dropdown
Just need to open popup menu in right sidebar and shows as theme studio
Hi,
I used the following source for WASM .NET 7 and faced the problem. Is it possible to post your sample for .NET 7?
Thank you
https://www.syncfusion.com/downloads/support/forum/164226/ze/WASMThemeSwitcher1510513162
Hi Sarah,
Please follow the below steps to create a Syncfusion Blazor WebAssembly app(Targeting: Net7.0) with theme switching .
Step 1: Create a Blazor WebAssembly Application in VS2022.
Step 2: Open ~/wwwroot/index.html file and add a function to set the theme as selected by using id value.
<html>
<head> ..... ..... .....
<link id="theme" rel='nofollow' href="_content/Syncfusion.Blazor.Themes/bootstrap4.css" rel="stylesheet" /> <script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js" type="text/javascript"></script> </head>
<body> ..... ..... ..... <script> function setTheme(theme) { document.getElementsByTagName('body')[0].style.display = 'none'; let synclink = document.getElementById('theme'); synclink.rel='nofollow' href = '_content/Syncfusion.Blazor.Themes/' + theme + '.css'; setTimeout(function () { document.getElementsByTagName('body')[0].style.display = 'block'; }, 300); } </script>
</body>
</html> |
Step 3: Open ~/Shared/MainLayout.razor file and add the below code snippet.
@inherits LayoutComponentBase @inject IJSRuntime JSRuntime; @using Syncfusion.Blazor.DropDowns;
<div class="page"> <div class="main"> <div class="top-row px-4"> <a rel='nofollow' href= http://blazor.net target="_blank" class="ml-md-auto">About</a> </div>
<div class="content px-4"> <br/> <div class="theme-switcher"> @*Theme switcher*@ <SfDropDownList TItem="ThemeDetails" TValue="string" @bind-Value="themeName" DataSource="@Themes"> <DropDownListFieldSettings Text="Text" Value="ID"></DropDownListFieldSettings> <DropDownListEvents TItem="ThemeDetails" TValue="string" ValueChange="OnThemeChange"></DropDownListEvents> </SfDropDownList> </div> <br/> @Body </div> </div> </div>
@code { private string themeName = "bootstrap4";
public class ThemeDetails { public string ID { get; set; } public string Text { get; set; } }
private List<ThemeDetails> Themes = new List<ThemeDetails>() { new ThemeDetails(){ ID = "material", Text = "Material" }, new ThemeDetails(){ ID = "bootstrap", Text = "Bootstrap" }, new ThemeDetails(){ ID = "fabric", Text = "Fabric" }, new ThemeDetails(){ ID = "bootstrap4", Text = "Bootstrap 4" }, new ThemeDetails(){ ID = "tailwind", Text = "TailWind"}, new ThemeDetails(){ ID = "tailwind-dark", Text = "TailWind Dark" }, new ThemeDetails(){ ID = "material-dark", Text = "Material Dark" }, new ThemeDetails(){ ID = "bootstrap-dark", Text = "Bootstrap Dark" }, new ThemeDetails(){ ID = "fabric-dark", Text = "Fabric Dark" }, new ThemeDetails(){ ID = "highcontrast", Text = "High Contrast" } };
public void OnThemeChange(Syncfusion.Blazor.DropDowns.ChangeEventArgs<string, ThemeDetails> args) { JSRuntime.InvokeAsync<object>("setTheme", args.ItemData.ID); } } |
Step 4: Open ~/Pages/ folder and add the required Syncfusion Blazor components in that pages. For example, we have added SfGrid component in ~/Pages/Index.razor page
Step 5: Run the application.
We have prepared a sample for your reference and the same can be downloaded from the below link.
Sample:
https://www.syncfusion.com/downloads/support/directtrac/general/ze/Sample-1803093875
Please let us know if you have any concerns.
Regards,
Bharat Ram H
Hello
Thank you very much for your sample.
1- How can the user's theme be saved so that the next time he opens the site, the same theme he chose in the past will be displayed?
2- I have designed some components. How can I find out what the theme of the website is so that I can set the color of my component accordingly?
Hi Sarah,
Query 1- How can the user's theme be saved so that the next time he opens the site, the same theme he chose in the past will be displayed?
You can achieve this by storing the selected theme in the browser's local storage using the Blazored.LocalStorage NuGet Package. Please refer to the following code snippet and sample for reference.
We have included a singleton service for storing the value obtained from local storage.
GetTheme.cs
namespace Sample.Shared { public class GetTheme { public string CurrentTheme { get; set; } } } |
Program.cs
using Blazored.LocalStorage; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Sample; using Sample.Shared; using Syncfusion.Blazor;
var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddSyncfusionBlazor(); builder.Services.AddBlazoredLocalStorage();
var host = builder.Build(); var localStorage = host.Services.GetRequiredService<ILocalStorageService>(); // Get a value from localStorage var value = await localStorage.GetItemAsync<string>("Theme"); if (value == null) { value = "bootstrap4"; } builder.Services.AddSingleton(new GetTheme{ CurrentTheme = value });
await builder.Build().RunAsync();
|
MainLayout.razor
@inherits LayoutComponentBase @inject IJSRuntime JSRuntime; @inject ILocalStorageService LocalStorage @inject GetTheme ThemeName; @using Blazored.LocalStorage; @using Syncfusion.Blazor.DropDowns;
<div class="page"> <div class="main"> <div class="top-row px-4"> <a rel='nofollow' href= http://blazor.net target="_blank" class="ml-md-auto">About</a> </div>
<div class="content px-4"> <br/> <div class="theme-switcher"> @*Theme switcher*@ <SfDropDownList TItem="ThemeDetails" TValue="string" @bind-Value="ThemeName.CurrentTheme" DataSource="@Themes"> <DropDownListFieldSettings Text="Text" Value="ID"></DropDownListFieldSettings> <DropDownListEvents TItem="ThemeDetails" TValue="string" ValueChange="OnThemeChange"></DropDownListEvents> </SfDropDownList> </div> <br/> @Body </div> </div> </div>
@code {
public class ThemeDetails { public string ID { get; set; } public string Text { get; set; } }
private List<ThemeDetails> Themes = new List<ThemeDetails>() { new ThemeDetails(){ ID = "material", Text = "Material" }, new ThemeDetails(){ ID = "bootstrap", Text = "Bootstrap" }, new ThemeDetails(){ ID = "fabric", Text = "Fabric" }, new ThemeDetails(){ ID = "bootstrap4", Text = "Bootstrap 4" }, new ThemeDetails(){ ID = "tailwind", Text = "TailWind"}, new ThemeDetails(){ ID = "tailwind-dark", Text = "TailWind Dark" }, new ThemeDetails(){ ID = "material-dark", Text = "Material Dark" }, new ThemeDetails(){ ID = "bootstrap-dark", Text = "Bootstrap Dark" }, new ThemeDetails(){ ID = "fabric-dark", Text = "Fabric Dark" }, new ThemeDetails(){ ID = "highcontrast", Text = "High Contrast" } };
public async void OnThemeChange(Syncfusion.Blazor.DropDowns.ChangeEventArgs<string, ThemeDetails> args) { await LocalStorage.SetItemAsync("Theme", args.ItemData.ID); JSRuntime.InvokeAsync<object>("setTheme", args.ItemData.ID); }
protected override void OnInitialized() { JSRuntime.InvokeAsync<object>("setTheme", ThemeName.CurrentTheme); } } |
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Sample-1388008885
Query 2- I have designed some components. How can I find out what the theme of the website is so that I can set the color of my component accordingly?
To determine the website's theme, you can inject the GetTheme service and use the CurrentTheme property to retrieve the current theme stored in the browser's local storage. Please refer to the following code snippet for reference:
MainLayout.razor
@inherits LayoutComponentBase @inject IJSRuntime JSRuntime; @inject ILocalStorageService LocalStorage @inject GetTheme ThemeName; @using Blazored.LocalStorage; @using Syncfusion.Blazor.DropDowns;
//… @*Theme switcher*@ <SfDropDownList TItem="ThemeDetails" TValue="string" @bind-Value="ThemeName.CurrentTheme" DataSource="@Themes"> <DropDownListFieldSettings Text="Text" Value="ID"></DropDownListFieldSettings> <DropDownListEvents TItem="ThemeDetails" TValue="string" ValueChange="OnThemeChange"></DropDownListEvents> </SfDropDownList> </div> <br/> @Body </div> </div> </div>
@code {
//… protected override void OnInitialized() { JSRuntime.InvokeAsync<object>("setTheme", ThemeName.CurrentTheme); } } |
Regards,
Bharat Ram
I'm using a SfDropDownList to choose between the defined themes, however I need to use a toggle button to switch between light and dark mode.
Is there somewhere on your website that shows me how to do this on Blazor?
Hi Joao,
Based on your query, we have developed a Blazor Web App targeting .NET 8.0 and implemented SfDropDownList to choose between the defined themes and also used a toggle button to switch between light and dark mode.
Please refer the following sample and get back to us if you have any other queries.
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/BlazorThemeSwitch517642431
Regards,
Subathra K
Hi BharatRam Harikrishnan,
I want to use your code in blazor web app .net 8. It has the following error.
Hi Sarah,
Based on your query, we came to know that you have you have used the code snippet that we have shared for Blazor WASM Standalone App targeting .NET 7.0 in the Blazor Web application which causes the issue. However, we have developed a Blazor Web App targeting .NET 8.0 with theme switching by implementing the code changes, and the application is now working correctly.
Please check the attached sample and get back to us if you have any other queries.
Regards,
Subathra K
Hi Subathra Kaliamoorthy,
Yes you are right. In the beginning, I worked on Blazer Web Assembly and now I work on Blazer Web App. Thank you for your reply. There is a problem, I use sfsidebar in MainLayout. The first time the screen is displayed, the number one image is displayed. Then, after we refresh the page with f5, image number 2 is displayed. This problem did not exist before applying the theme. The first image is correct.
image1:
image2:
Hi Sarah,
We investigated the reported issue with layout misalignment occurring when incorporating the dynamic theme switching code and successfully replicated it on our end. We identified the root cause: changing the CSS "display" property from "none" to "block" during theme switching, which resulted in the layout misalignment. We resolved this by using the "visibility" property instead of "display", as shown below.
Here, we have also attached the sample for your reference. Please check it and get back to us if you have any other queries.
Regards,
Subathra K
Hello
The problem was solved.
Thanks
Hello
The problem was solved
thank you
Hi Sarah,
Thanks for the update. Please get back to us if you need any other assistance.
Regards,
Subathra K
Could you kindly provide a sample where you use .NET8 Blazor Web App with Interactive Auto Render Mode and per component interactivity?
I followed what you have here but on navigation the page seems to reload the html and lose the current theme unless I refresh the page entirely.
Hi Albert,
Based on the provided details, we have developed a Blazor Web App targeting .NET 8.0 with Interactive Auto Render Mode and per component interactivity. Here, we have included a theme-switching feature designed to persist the user's selected theme across different pages.
During our testing, we were unable to reproduce the issue where the current theme is lost upon navigation to another page. The theme consistently remains as expected when moving between pages.
Please check the attached sample for your reference. If the issue with theme persistence continues to occur on your end, please provide us with a sample/video representation that reproduces the problem, so that we can investigate further and assist you promptly
Regards,
Subathra K
Hi
Thanks for your response.
I have played around with your sample code and here are my observations.
A few questions.
I've attached a few videos too. Kindly advise on the way forward. Thanks.
Hi Albert,
Thank you for reaching out. We've reviewed your query and would like to clarify how Blazor Web App in .NET 8.0 handles static web assets when using the Per Page/Component Interactive location.
When a Blazor component is rendered with @rendermode Interactive, Blazor ensures that the necessary assets for interactivity are loaded before the component becomes interactive. For example, if you have interactive components in both Home.razor and Counter.razor pages, Blazor will load and apply the default themes as you navigate between these pages. However, if you navigate from an interactive page like Home.razor to a server-side rendered (SSR) page like Weather.razor, the theme value persist because the interactive assets are not loaded in SSR mode.
To ensure that the selected theme persists across all pages, we recommend setting the theme in the OnAfterRenderAsync method of each page. This will ensure consistency, regardless of whether the page is rendered interactively or server-side.
Please refer to the attached sample and video for further guidance. If you have any additional questions, feel free to reach out to us.
Regards,
Subathra K.
Hi
Thank you for your response. It appears the sample attached is not updated to reflect your recommendation.
Hi Albert,
Sorry for the delay in response.
Based on your query, we would like to inform you that the attached sample clarifies how the theme value is changing when navigating between pages as mentioned in the previously attached video. However, if you want to set the theme in the OnAfterRenderAsync method of each page like mentioned below, you can refer the attached sample for guidance.
Please refer the attached sample and get back to us if you have any further queries.
Regards,
Subathra K.