Skip to content

Commit 051f72d

Browse files
Merge pull request #1 from SyncfusionExamples/Sample
Added the Theme Sample for the KB.
2 parents 8854fe1 + afc72cb commit 051f72d

37 files changed

+1141
-2
lines changed

README.md

+84-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,84 @@
1-
# -How-to-Automatically-Switch-Syncfusion-Control-Themes-Based-on-Device-Selected-Theme-in-.NET-MAUI
2-
This repository contains a sample explaining how to automatically switch Syncfusion control themes based on device selected theme in .NET MAUI. Tokens: maui, theme, device-theme, Syncfusion-theme
1+
This article explains how to automatically switch [.NET MAUI Syncfusion control](https://www.syncfusion.com/maui-controls) themes based on the device-selected theme. This can be achieved by using [SyncfusionThemeResourceDictionary](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Themes.SyncfusionThemeResourceDictionary.html).
2+
3+
To enable automatic theme switching for Syncfusion controls based on the device's selected theme in a .NET MAUI application, you can utilize the `OnAppearing` method to assign the Syncfusion [VisualTheme](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Themes.SyncfusionThemeResourceDictionary.html#Syncfusion_Maui_Themes_SyncfusionThemeResourceDictionary_VisualTheme). Additionally, handling the `RequestedThemeChanged` event allows for dynamic updates to the Syncfusion controls' theme when the device's theme changes at runtime.
4+
5+
**App.xaml Configuration**
6+
7+
Ensure that your App.xaml includes the `SyncfusionThemeResourceDictionary`:
8+
9+
```
10+
<Application ...
11+
xmlns:themes="clr-namespace:Syncfusion.Maui.Themes;assembly=Syncfusion.Maui.Core">
12+
<Application.Resources>
13+
<ResourceDictionary>
14+
<ResourceDictionary.MergedDictionaries>
15+
<themes:SyncfusionThemeResourceDictionary />
16+
...
17+
</ResourceDictionary.MergedDictionaries>
18+
</ResourceDictionary>
19+
</Application.Resources>
20+
</Application>
21+
```
22+
23+
**XAML**
24+
25+
```
26+
//Mainpage.xaml
27+
28+
<VerticalStackLayout Padding="30,0" Spacing="25">
29+
<buttons:SfButton x:Name="CounterBtn" Text="Click me" Clicked="OnCounterClicked"
30+
HorizontalOptions="Fill" />
31+
</VerticalStackLayout>
32+
```
33+
34+
**C#**
35+
36+
1. Override the `OnAppearing` method to apply the current theme and set up an event handler for theme changes.
37+
2. Implement the `OnRequestedThemeChanged` event handler to respond to theme changes during runtime.
38+
3. Define the `ApplyTheme` method to update the Syncfusion theme based on the current application theme.
39+
40+
```csharp
41+
//Mainpage.xaml.cs
42+
43+
protected override void OnAppearing()
44+
{
45+
if (Application.Current != null)
46+
{
47+
this.ApplyTheme(Application.Current.RequestedTheme);
48+
Application.Current.RequestedThemeChanged += OnRequestedThemeChanged;
49+
}
50+
base.OnAppearing();
51+
}
52+
53+
private void OnRequestedThemeChanged(object? sender, AppThemeChangedEventArgs e)
54+
{
55+
this.ApplyTheme(e.RequestedTheme);
56+
}
57+
58+
public void ApplyTheme(AppTheme appTheme)
59+
{
60+
if (Application.Current != null)
61+
{
62+
ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
63+
if (mergedDictionaries != null)
64+
{
65+
var syncTheme = mergedDictionaries.OfType<SyncfusionThemeResourceDictionary>().FirstOrDefault();
66+
if (syncTheme != null)
67+
{
68+
if (appTheme is AppTheme.Light)
69+
{
70+
syncTheme.VisualTheme = SfVisuals.MaterialLight;
71+
}
72+
else
73+
{
74+
syncTheme.VisualTheme = SfVisuals.MaterialDark;
75+
}
76+
}
77+
}
78+
}
79+
}
80+
```
81+
82+
**Output**
83+
84+
![Theme_Demo.gif](https://support.bolddesk.com/kb/agent/attachment/article/17196/inline?token=eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjI4NDcxIiwib3JnaWQiOiIzIiwiaXNzIjoic3VwcG9ydC5ib2xkZGVzay5jb20ifQ.YNDjr4zoII7A6wHES18wM0xTiidGYFkQ_t7WmRjcdWg)

ThemeSample/App.xaml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version = "1.0" encoding = "UTF-8" ?>
2+
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
xmlns:local="clr-namespace:ThemeSample"
5+
xmlns:themes="clr-namespace:Syncfusion.Maui.Themes;assembly=Syncfusion.Maui.Core"
6+
x:Class="ThemeSample.App">
7+
<Application.Resources>
8+
<ResourceDictionary>
9+
<ResourceDictionary.MergedDictionaries>
10+
<themes:SyncfusionThemeResourceDictionary />
11+
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
12+
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
13+
</ResourceDictionary.MergedDictionaries>
14+
</ResourceDictionary>
15+
</Application.Resources>
16+
</Application>

ThemeSample/App.xaml.cs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace ThemeSample
2+
{
3+
public partial class App : Application
4+
{
5+
public App()
6+
{
7+
InitializeComponent();
8+
9+
MainPage = new AppShell();
10+
}
11+
}
12+
}

ThemeSample/AppShell.xaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<Shell
3+
x:Class="ThemeSample.AppShell"
4+
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
6+
xmlns:local="clr-namespace:ThemeSample"
7+
Shell.FlyoutBehavior="Disabled"
8+
Title="ThemeSample">
9+
10+
<ShellContent
11+
Title="Home"
12+
ContentTemplate="{DataTemplate local:MainPage}"
13+
Route="MainPage" />
14+
15+
</Shell>

ThemeSample/AppShell.xaml.cs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace ThemeSample
2+
{
3+
public partial class AppShell : Shell
4+
{
5+
public AppShell()
6+
{
7+
InitializeComponent();
8+
}
9+
}
10+
}

ThemeSample/MainPage.xaml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
x:Class="ThemeSample.MainPage"
5+
xmlns:buttons="clr-namespace:Syncfusion.Maui.Buttons;assembly=Syncfusion.Maui.Buttons">
6+
7+
<ScrollView>
8+
<VerticalStackLayout
9+
Padding="30,0"
10+
Spacing="25">
11+
12+
<buttons:SfButton Text="Click me"/>
13+
</VerticalStackLayout>
14+
</ScrollView>
15+
16+
</ContentPage>

ThemeSample/MainPage.xaml.cs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using Syncfusion.Maui.Themes;
2+
3+
namespace ThemeSample
4+
{
5+
public partial class MainPage : ContentPage
6+
{
7+
public MainPage()
8+
{
9+
InitializeComponent();
10+
}
11+
12+
protected override void OnAppearing()
13+
{
14+
if (Application.Current != null)
15+
{
16+
this.ApplyTheme(Application.Current.RequestedTheme);
17+
Application.Current.RequestedThemeChanged += OnRequestedThemeChanged;
18+
}
19+
base.OnAppearing();
20+
}
21+
22+
private void OnRequestedThemeChanged(object? sender, AppThemeChangedEventArgs e)
23+
{
24+
this.ApplyTheme(e.RequestedTheme);
25+
}
26+
27+
public void ApplyTheme(AppTheme appTheme)
28+
{
29+
if (Application.Current != null)
30+
{
31+
ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
32+
if (mergedDictionaries != null)
33+
{
34+
var syncTheme = mergedDictionaries.OfType<SyncfusionThemeResourceDictionary>().FirstOrDefault();
35+
if (syncTheme != null)
36+
{
37+
if (appTheme is AppTheme.Light)
38+
{
39+
syncTheme.VisualTheme = SfVisuals.MaterialLight;
40+
}
41+
else
42+
{
43+
syncTheme.VisualTheme = SfVisuals.MaterialDark;
44+
}
45+
}
46+
}
47+
}
48+
}
49+
}
50+
51+
}

ThemeSample/MauiProgram.cs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Microsoft.Extensions.Logging;
2+
using Syncfusion.Maui.Core.Hosting;
3+
4+
namespace ThemeSample
5+
{
6+
public static class MauiProgram
7+
{
8+
public static MauiApp CreateMauiApp()
9+
{
10+
var builder = MauiApp.CreateBuilder();
11+
builder
12+
.UseMauiApp<App>()
13+
.ConfigureSyncfusionCore()
14+
.ConfigureFonts(fonts =>
15+
{
16+
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
17+
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
18+
});
19+
20+
#if DEBUG
21+
builder.Logging.AddDebug();
22+
#endif
23+
24+
return builder.Build();
25+
}
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
4+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
5+
<uses-permission android:name="android.permission.INTERNET" />
6+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Android.App;
2+
using Android.Content.PM;
3+
using Android.OS;
4+
5+
namespace ThemeSample
6+
{
7+
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
8+
public class MainActivity : MauiAppCompatActivity
9+
{
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Android.App;
2+
using Android.Runtime;
3+
4+
namespace ThemeSample
5+
{
6+
[Application]
7+
public class MainApplication : MauiApplication
8+
{
9+
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
10+
: base(handle, ownership)
11+
{
12+
}
13+
14+
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<color name="colorPrimary">#512BD4</color>
4+
<color name="colorPrimaryDark">#2B0B98</color>
5+
<color name="colorAccent">#2B0B98</color>
6+
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Foundation;
2+
3+
namespace ThemeSample
4+
{
5+
[Register("AppDelegate")]
6+
public class AppDelegate : MauiUIApplicationDelegate
7+
{
8+
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->
5+
<dict>
6+
<!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->
7+
<key>com.apple.security.app-sandbox</key>
8+
<true/>
9+
<!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->
10+
<key>com.apple.security.network.client</key>
11+
<true/>
12+
</dict>
13+
</plist>
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<!-- The Mac App Store requires you specify if the app uses encryption. -->
6+
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->
7+
<!-- <key>ITSAppUsesNonExemptEncryption</key> -->
8+
<!-- Please indicate <true/> or <false/> here. -->
9+
10+
<!-- Specify the category for your app here. -->
11+
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->
12+
<!-- <key>LSApplicationCategoryType</key> -->
13+
<!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->
14+
<key>UIDeviceFamily</key>
15+
<array>
16+
<integer>2</integer>
17+
</array>
18+
<key>UIRequiredDeviceCapabilities</key>
19+
<array>
20+
<string>arm64</string>
21+
</array>
22+
<key>UISupportedInterfaceOrientations</key>
23+
<array>
24+
<string>UIInterfaceOrientationPortrait</string>
25+
<string>UIInterfaceOrientationLandscapeLeft</string>
26+
<string>UIInterfaceOrientationLandscapeRight</string>
27+
</array>
28+
<key>UISupportedInterfaceOrientations~ipad</key>
29+
<array>
30+
<string>UIInterfaceOrientationPortrait</string>
31+
<string>UIInterfaceOrientationPortraitUpsideDown</string>
32+
<string>UIInterfaceOrientationLandscapeLeft</string>
33+
<string>UIInterfaceOrientationLandscapeRight</string>
34+
</array>
35+
<key>XSAppIconAssets</key>
36+
<string>Assets.xcassets/appicon.appiconset</string>
37+
</dict>
38+
</plist>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using ObjCRuntime;
2+
using UIKit;
3+
4+
namespace ThemeSample
5+
{
6+
public class Program
7+
{
8+
// This is the main entry point of the application.
9+
static void Main(string[] args)
10+
{
11+
// if you want to use a different Application Delegate class from "AppDelegate"
12+
// you can specify it here.
13+
UIApplication.Main(args, null, typeof(AppDelegate));
14+
}
15+
}
16+
}

ThemeSample/Platforms/Tizen/Main.cs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Microsoft.Maui;
2+
using Microsoft.Maui.Hosting;
3+
using System;
4+
5+
namespace ThemeSample
6+
{
7+
internal class Program : MauiApplication
8+
{
9+
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
10+
11+
static void Main(string[] args)
12+
{
13+
var app = new Program();
14+
app.Run(args);
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)