Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 66 additions & 2 deletions doc/Learn/ThemeService/HowTo-UseThemeService.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
uid: Uno.Extensions.ThemeService.Overview
---
<!--markdownlint-disable MD051 -->
# How to use Theme Service

This topic explains how to use the `ThemeService` for runtime theme switching and persisting user theme preferences.
Expand All @@ -12,13 +13,15 @@ This topic explains how to use the `ThemeService` for runtime theme switching an

## Step-by-step (Typical Usage with DI)

### [MVVM](#tab/mvvm)

1. **Consume ThemeService**: Inject the `ThemeService` into your view models or other services where you need to manipulate the theme.

```csharp
public class SettingsViewModel
{
private readonly IThemeService _themeService;

public SettingsViewModel(IThemeService themeService)
{
_themeService = themeService;
Expand All @@ -33,6 +36,67 @@ This topic explains how to use the `ThemeService` for runtime theme switching an
}
```

### [MVUX](#tab/mvux)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion here is that we don't include this as part of the ThemeService docs but we should create a Recipe Book docs entry for this usage in Chefs: https://github.com/unoplatform/uno.chefs/blob/198923fcd69d416fd3901be2fe4d58fecd74421b/Chefs/Presentation/SettingsModel.cs#L26-L38

https://platform.uno/docs/articles/external/uno.chefs/doc/RecipeBooksOverview.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that ThemeChangedMessage in there is quite cool and the ISettingsService... Can we not get a SettingsService generally available in extensions? that would really be cool! to have just to call this to automatically switch theme or localization! is this think-able?


1. **Consume ThemeService**: Inject the `ThemeService` into your models or other services where you need to manipulate the theme.
2. **Bind to View**: Use a State or Command to bind your UI in your XAML. <!-- TODO: Add Links to each of the tabs -->

### [Model](#tab/mvux/csharp)

In case you want to use it together with a State, e.g. to bind a control to the current theme trigger a Task with each Time, the Value changes, here is a simple example:

```cssharp
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code block language identifier should be 'csharp' not 'cssharp'.

Suggested change
```cssharp
```csharp

Copilot uses AI. Check for mistakes.
namespace UnoAppName.Presentation.ViewModels;
public partial record MainModel
{
private readonly IThemeService _themeService;

public MainModel(
IThemeService themeService)
{
_themeService = themeService;
}

public IState<bool> IsDarkMode => State<bool>.Value(this, () => _themeService.Theme == AppTheme.Dark)
.ForEach(SwitchThemeAsync);

public async ValueTask SwitchThemeAsync(bool item,CancellationToken ctk = default)
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after comma in parameter list. Should be 'bool item, CancellationToken ctk = default'.

Suggested change
public async ValueTask SwitchThemeAsync(bool item,CancellationToken ctk = default)
public async ValueTask SwitchThemeAsync(bool item, CancellationToken ctk = default)

Copilot uses AI. Check for mistakes.
{

_ = item switch
{
true => await _themeService.SetThemeAsync(AppTheme.Light),
false => await _themeService.SetThemeAsync(AppTheme.Dark)
Comment on lines +68 to +69
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The boolean logic is inverted. When item is true (toggle is on), it should set Dark theme, not Light theme. The switch cases should be reversed.

Suggested change
true => await _themeService.SetThemeAsync(AppTheme.Light),
false => await _themeService.SetThemeAsync(AppTheme.Dark)
true => await _themeService.SetThemeAsync(AppTheme.Dark),
false => await _themeService.SetThemeAsync(AppTheme.Light)

Copilot uses AI. Check for mistakes.
};
}
```

### [View](#tab/mvux/xaml)

With this, you can bind the `IsDarkMode` state to a toggle switch in your XAML:

```xml
<ToggleSwitch x:Name="ThemeSwitch"
Grid.Row="1"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,0,10,0"
IsOn="{Binding Path=IsDarkMode, Mode=TwoWay}"
Foreground="{ThemeResource OnPrimaryContainerBrush}"
Style="{ThemeResource ToggleSwitchStyle}">
<ToggleSwitch.OnContent>
<FontIcon Glyph="&#xE708;"/>
</ToggleSwitch.OnContent>
<ToggleSwitch.OffContent>
<FontIcon Glyph="&#xE706;"/>
</ToggleSwitch.OffContent>
</ToggleSwitch>
```

<!-- TODO: Check if IsOn can get changed to CommandBinding Extensions usage of #1391 #1309 #1310 -->

---

## Step-by-step (Manual Registration without DI or Advanced Scenarios)

If you are *not* using DI, Extensions, or require more control over the registration process, you can manually register the `ThemeService`:
Expand All @@ -58,4 +122,4 @@ If you are *not* using DI, Extensions, or require more control over the registra

## Source Code

[ThemeService Implementation](https://github.com/unoplatform/uno.extensions/blob/51c9c1ef14f686363f946588733faecc5a1863ff/src/Uno.Extensions.Core.UI/Toolkit/ThemeService.cs)
[!code-csharp [ThemeService Implementation](https://github.com/unoplatform/uno.extensions/blob/51c9c1ef14f686363f946588733faecc5a1863ff/src/Uno.Extensions.Core.UI/Toolkit/ThemeService.cs)]
Loading