How to Handle Theme Switching
Problem
Currently, there is no way to switch application themes at runtime from any layer, including view models. There is also a need to have a way to store the current theme and be able to initialize the app to the persisted theme preference.
Solution
The Uno.Extensions library addresses this problem by providing an injectable implementation of an IThemeService interface that can be registered as part of the IHostBuilder from Uno.Extensions.Hosting.
Adding ThemeService
To integrate ThemeService in your Uno application, follow these steps:
App Startup Configuration
- Register the
IThemeServicein your app startup:
public partial class App : Application
{
protected async override void OnLaunched(LaunchActivatedEventArgs args)
{
var builder = this.CreateBuilder(args)
.Configure(host => host
.UseThemeSwitching()
);
// Code omitted for brevity
}
}
- Consume the ThemeService in your view model:
public partial record SettingsModel
{
private readonly IThemeService _themeService;
public SettingsModel(IThemeService themeService)
{
_themeService = themeService;
}
public IList<AppTheme> ThemeOptions => Enum.GetValues(typeof(AppTheme)).Cast<AppTheme>().ToList();
public IState<AppTheme> Theme => State
.Value(this, () => _themeService.Theme)
.ForEach(async (theme, _) => await _themeService.SetThemeAsync(theme));
}
- Use the
ThemeIStatein your XAML to bind to the current theme and allow the user to change it:
<ComboBox ItemsSource="{Binding ThemeOptions}"
SelectedItem="{Binding Theme, Mode=TwoWay}"
HorizontalAlignment="Right" />