Plugin.Maui.Theme is a lightweight library for managing themes in .NET MAUI applications. It enables dynamic switching of styles defined in ResourceDictionary without restarting the app. The core component, ThemeService, implemented as a singleton, handles theme registration, selection, and synchronization with the application's resource dictionaries. The library supports the ThemeChanged event, notifying subscribers when the active theme changes—making it ideal for building adaptive interfaces. Initialization can be done programmatically, with automatic detection of the currently active theme at launch and the ability to set a default style. All operations are thoroughly validated to prevent errors and ensure smooth integration.
$ dotnet add package Plugin.Maui.ThemeThe Plugin.Maui.Theme library provides a powerful theme management service for .NET MAUI applications, allowing dynamic switching of visual styles.
ThemeServiceA singleton service that manages application themes via ResourceDictionary.
ThemeService.Current: Static property to access the current instance._themes: Dictionary containing registered themes (Dictionary<int, ResourceDictionary>)._appResources: Reference to the application's MergedDictionaries._currentDict: Currently applied ResourceDictionary._currentTheme: Key-value pair representing the active theme.InitAppResourcesInitializes a reference to the application's MergedDictionaries.
public void InitAppResources(ResourceDictionary resource)
💥Throws ArgumentNullException if the resource is null.
This method extends the functionality for working with resource dictionaries, allowing you to get a resource dictionary's key by its type rather than a hardcoded name. This method is useful when you're working with themes or resource dictionaries that are implemented as separate classes. It helps you avoid using magic strings for keys and instead uses type-safe operations.
public bool TryGetKeyByType<T>(out int key) where T : ResourceDictionary
The AddThemes method provides a convenient way to register multiple themes within the application without requiring explicit keys for each.
public IThemeService AddThemes(params ResourceDictionary[] resources) or
public IThemeService AddThemes(params KeyValuePair<int, ResourceDictionary>[] resources)
This method is designed for scenarios where you have a collection of ResourceDictionary instances that you wish to register as themes, and you're comfortable with the system automatically assigning sequential keys to them, starting from the next available index.
resources: An array of ResourceDictionary objects that will be registered as themes.IThemeService instance. This allows for fluent chaining of method calls, enabling you to perform multiple theme-related operations in a concise manner (e.g., themeService.AddThemes(...).SetCurrentTheme(...)).Switches the application to the specified theme.
public void ChangeTheme(int key)
🧯 Throws exceptions if the theme is not found or InitAppResources was not called.
Triggered whenever the theme is changed:
public event EventHandler<ThemeChangedEventArgs>? ThemeChanged;
public record ThemeChangedEventArgs(int KeyTheme, ResourceDictionary NewTheme);
Used to notify subscribers about theme changes.
A DynamicResource is a reference to a resource that is resolved just before it's used. This means that if the value of the resource changes while the application is running, all elements using that DynamicResource will automatically update.
Unlike a StaticResource, which is resolved only once when the application starts, a DynamicResource provides flexibility and allows for a dynamic user interface.
Using a DynamicResource is very simple. You just need to specify the resource key in your XAML markup.
When using the AddThemes methods, it's important to understand how keys are assigned to the styles.
If you first call:
public IThemeService AddThemes(params KeyValuePair<int, ResourceDictionary>[] resources)
And then call:
public IThemeService AddThemes(params ResourceDictionary[] resources)
The key for the second set of resources will be calculated using the formula: maximum_key + 1, where maximum_key is the highest numerical key passed in the first call.
If your first call included themes with keys 1 and 5, the first resource in the second call will automatically be assigned the key 6.
In the App.xaml.cs class, you can use ThemeService like this:
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts();
// Your theme service initialization
// This line assumes 'UseTheme()' is an extension method
// on MauiAppBuilder or configures a theme service.
builder.UseTheme(); // <-- Call your UseTheme() method here
return builder.Build();
}
public App(IThemeService themeService)
{
InitializeComponent();
themeService.InitAppResources(Resources)
.AddThemes(new KeyValuePair<int, ResourceDictionary>(99, new RedTheme()))
.AddThemes(new BlueTheme(), new DarkTheme());
themeService.ThemeChanged += Current_ThemeChanged;
}
🛠 Author: Fishman 📅 Last updated: 11.2025
We're thrilled to announce that the preparation of version 9.2.0 was significantly supported by Алексом Добрыниным. His contributions were invaluable in bringing this release to fruition.
This project is licensed under the Boost Software License – Version 1.0 – August 17th, 2003.