IAppearanceService¶
IAppearanceService provides a platform-agnostic way to access the appearance choices supported by the DeltaDesign theme and apply the chosen one. It allows your ViewModel to change the theme variant, color palette, and layout density at runtime without referencing any UI framework type directly.
Main features include:
- Theme variants — Provides access to available theme variants (
LightandDark). - Color palettes — Provides access to the color palettes in the DeltaDesign theme, such as
Nova,Helios,Terra,Vega, andAtlas. - Layout densities — Provides access to the layout densities available in the DeltaDesign theme (
Compact,Standard, andSpacious). - Immediate application — You can change a dedicated option of
IAppearanceServiceto immediately change the corresponding theme setting. - Bindable to selectors — The service implements the
INotifyPropertyChangedinterface and is designed to be bound directly to a ribbon gallery, a combo box, a menu, or any other selector.
Interface Definition¶
public interface IAppearanceService : INotifyPropertyChanged
{
// A list of available theme variants (light/dark).
IReadOnlyList<IAppearanceOption> ThemeVariants { get; }
// A list of available color palettes.
IReadOnlyList<IAppearanceOption> Palettes { get; }
// A list of availalbe layout densities.
IReadOnlyList<IAppearanceOption> Densities { get; }
// The chosen theme variant. Assigning it recolors the running application at once.
IAppearanceOption SelectedThemeVariant { get; set; }
// The chosen theme palette. Assigning it recolors the running application at once.
IAppearanceOption SelectedPalette { get; set; }
// The chosen density. Assigning it resizes the controls of the running application at once.
IAppearanceOption SelectedDensity { get; set; }
}
IAppearanceOption¶
Each item in the ThemeVariants, Palettes, and Densities lists implements the IAppearanceOption interface:
All service interfaces are free of references to UI framework types. The IAppearanceOption interface follows the same principle. It only contains a string property that specifies the caption of a theme option. However, actual implementations of the IAppearanceOption interface return richer objects, listed below:
IAppearanceOption Implementation |
Description |
|---|---|
ThemeOption class |
A light or dark theme variant. Additional properties include: - ThemeOption.Variant (of the Avalonia.Styling.ThemeVariant type) — the theme variant associated with this option. |
PaletteOption class |
A color palette. Additional properties include: - PaletteOption.Palette — the palette applied when this option is chosen (Nova, Helios, Terra, Vega, Atlas, etc.);- PaletteOption.Accent — a read-only Brush object that represents the current palette. The PaletteOption.Accent property allows you to show a color swatch in a selector, so the user can preview a palette before picking it. |
DensityOption class |
A layout density. Additional properties include: - DensityOption.Density — the density applied when this option is chosen (Compact, Standard, or Spacious). |
These objects are returned by the IAppearanceService actual implementation. For instance, the actual return value of IAppearanceService.SelectedPalette is a PaletteOption object.
How to Use IAppearanceService¶
- In your ViewModel, expose the
IAppearanceServiceservice as a property. - In your View, bind your selector controls to the members of this property.
Access the Service¶
You need to access the IAppearanceService service in your ViewModel to expose it as a property.
There are two ways to access an IAppearanceService object in a ViewModel:
- Through the
Service<T>()helper method. This is a convenient approach to obtain registered application services shipped with the Eremex Controls library. - Through constructor injection.
Service() Helper¶
Implement a helper Service<T>() method in your ViewModel to get a requested service using the static ApplicationServicesContext.GetRequiredService<T>() method.
using Eremex.AvaloniaUI.Controls.ApplicationServices;
using CommunityToolkit.Mvvm.Input;
public partial class MyViewModel : ObservableObject
{
// Provides access to any registered service
protected static T Service<T>() where T : class
=> ApplicationServicesContext.GetRequiredService<T>();
public IAppearanceService Appearance { get; } = Service<IAppearanceService>();
}
In the App.axaml.cs file, ensure that Eremex application services are registered using SimpleServiceProvider and ApplicationServicesContext as follows:
public class App : Application
{
public override void OnFrameworkInitializationCompleted()
{
RegisterApplicationServices();
//...
}
static void RegisterApplicationServices()
{
// Register built-in services.
var serviceProvider = new SimpleServiceProvider();
ApplicationServicesContext.RegisterApplicationServices(serviceProvider.AddSingleton);
ApplicationServicesContext.SetCurrent(serviceProvider);
}
}
Constructor Injection¶
Implement a constructor in your ViewModel with IAppearanceService as a parameter. When you instantiate the ViewModel, pass the service object to this constructor.
public partial class MainViewModel : ObservableObject
{
public MainViewModel(IAppearanceService appearance)
{
Appearance = appearance;
}
public IAppearanceService Appearance { get; }
}
Expose the Service from the ViewModel¶
Expose IAppearanceService as a public property. UI controls in the View will bind to it directly:
The following example creates the Appearance property of the IAppearanceService type and initializes it using the Service<T> helper.
public partial class MainViewModel : ObservableObject
{
public IAppearanceService Appearance { get; }
public MainViewModel(ThemeVariant? startupThemeVariant = null)
{
Appearance = Service<IAppearanceService>();
Appearance.SelectedThemeVariant = FindTheme(startupThemeVariant);
//...
}
private IAppearanceOption? FindTheme(ThemeVariant? variant)
=> variant is null
? null
: Appearance.Themes.FirstOrDefault(
x => string.Equals(x.Header, variant.ToString(), StringComparison.OrdinalIgnoreCase));
// Provides access to any registered service
protected static T Service<T>() where T : class
=> ApplicationServicesContext.GetRequiredService<T>();
}