In This Article

Getting Started

Actipro's themes for Avalonia consist of control themes, theme resources (brushes, thicknesses, etc.), glyphs, and more. Theme resources are dynamically generated by a theme generator that examines a theme definition's options. The result is a beautiful and very flexible theme that is not limited to statically defined resources.

Add NuGet Packages

Themes is included with the ActiproSoftware.Controls.Avalonia package (view on nuget.org), so add a reference to that package.

Optionally add references to the ActiproSoftware.Controls.Avalonia.Themes.ColorPicker package (view on nuget.org) and/or ActiproSoftware.Controls.Avalonia.Themes.DataGrid package (view on nuget.org) if Actipro themes will be used with these native controls.

For additional information on NuGet packages, please refer to the NuGet Packages and Feeds topic.

Theme Variants

Avalonia's theme system uses theme variants to request theme assets for an application. The theme variant is usually either Light or Dark. Actipro's themes define assets for both the Light and Dark theme variants, allowing an application to instantly flip to another theme variant without having to reload the entire theme.

Tip

See the external How to Use Theme Variants topic in the Avalonia documentation for additional details on the basics of theme variants.

Application-Wide Theme Variant

Avalonia applications will either use a light or dark theme variant by default, depending on the operating system's settings. If the operating system is configured to use a light appearance for applications, then an Avalonia application will default to a light theme variant, and vice versa. The final resolved theme variant used in an application is designated by the Application.ActualThemeVariant property.

The application-wide theme variant can be manually specified by setting the Application.RequestedThemeVariant property. This overrides the default behavior and forces a specific theme variant to be used.

Application.RequestedThemeVariant Example

The following example shows how to request that an application always load using a Dark theme variant.

<Application ... RequestedThemeVariant="Dark">
	...
</Application>

Hierarchy-Specific Theme Variant

It is possible to request a different theme variant for a specific subtree of visuals. This can be useful for scenarios where you wish to have a mix of multiple theme variants in use at the same time. For instance, you may wish for the left side navigation of a window to use a dark theme, but the rest of the application, such as the content area, should use a light theme.

Screenshot

A combination of dark and light theme variants

Avalonia's ThemeVariantScope control is used to tell a subtree of visuals to use an alternate theme variant from the one that would have normally been used, whether that higher level variant comes from another ancestor ThemeVariantScope or falls back to the Application.ActualThemeVariant.

ThemeVariantScope Example

The following example assumes the application has a Dark theme variant in place and shows how a ThemeVariantScope control can tell its subtree of visuals to use a Light theme variant instead.

<StackPanel>
	<Button Content="Dark Button" />
	<ThemeVariantScope RequestedThemeVariant="Light">
		<Button Content="Light Button" />
	</ThemeVariantScope>
</StackPanel>

Toggling Light/Dark Theme Variants

It's easy to toggle an application between light and dark theme variants. If the entire application should be updated, set the Application.RequestedThemeVariant property to the new theme variant. Or if only a subtree of visuals should be updated, set the containing ThemeVariantScope.RequestedThemeVariant property to the new theme variant instead.

Tip

Place a ToggleThemeButton control in the user interface to give the end user the ability to toggle between light and dark themes.

Using Actipro Themes

Actipro's themes can be integrated by adding a special ModernTheme class, which inherits Avalonia's Styles class, to an application's Application.Styles collection.

The ModernTheme class has several settings that tell it which theme assets to dynamically load into the Application, making them available for use.

App.xaml

An instance of ModernTheme can be placed directly in Application.Styles in XAML.

The following example shows how to load the free Actipro themes for most native Avalonia controls and free Actipro controls.

<Application
	x:Class="MyCompany.App"
	xmlns="https://github.com/avaloniaui"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
	>
	<Application.Styles>

		<!-- NOTE: Any Styles included above the ModernTheme can be overwritten by the Actipro themes -->

		<actipro:ModernTheme />

		<!-- NOTE: Any Styles included below the ModernTheme cannot be overwritten by the Actipro themes -->

	</Application.Styles>
</Application>
Note

See the "Includes Setting" section below for details on how to include themes for Actipro Avalonia UI Pro and optional native Avalonia controls.

Important

The order of entries in the Application.Styles is important. For instance, if the Avalonia Fluent theme is also loaded in Application.Styles after the ModernTheme entry, its control themes will take precedence over Actipro's theme.

Includes Setting

The ModernTheme.Includes property can be set to a ThemeStyleIncludes flags enumeration value to indicate the styles to include from various additional Actipro assemblies that are used within the application.

It is set to None by default, which means simply include core native Avalonia control themes, along with themes for Actipro's Shared Library controls, but nothing additional.

Since the property uses a flags enumeration, more than one value can be specified depending on your needs.

Value Description
None No additional Actipro assembly styles beyond those for the ActiproSoftware.Controls.Avalonia NuGet package are included.
NativeColorPicker Styles for all assemblies in the ActiproSoftware.Controls.Avalonia.Themes.ColorPicker NuGet package.
NativeDataGrid Styles for all assemblies in the ActiproSoftware.Controls.Avalonia.Themes.DataGrid NuGet package.
Pro Styles for all assemblies in the ActiproSoftware.Controls.Avalonia.Pro NuGet package.
All Styles for all assemblies and NuGet packages listed above.
Tip

See the Deployment topic for details on what is included in each NuGet package offering. Be sure to reference the appropriate NuGet packages mentioned above before adding related ThemeStyleIncludes values.

Usage Examples

When only using Actipro's free Shared Library and native Avalonia controls:

<Application ... xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui">
	<Application.Styles>

		<actipro:ModernTheme />

	</Application.Styles>
</Application>

When using Actipro's optional themes for the native ColorPicker and DataGrid controls, but no Actipro Pro controls:

<Application ... xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui">
	<Application.Styles>

		<actipro:ModernTheme Includes="NativeColorPicker, NativeDataGrid" />

	</Application.Styles>
</Application>

When using Actipro's Pro controls, but not the native ColorPicker or DataGrid controls:

<Application ... xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui">
	<Application.Styles>

		<actipro:ModernTheme Includes="Pro" />

	</Application.Styles>
</Application>

When using all controls:

<Application ... xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui">
	<Application.Styles>

		<actipro:ModernTheme Includes="All" />

	</Application.Styles>
</Application>
Warning

The ModernTheme.Includes property dynamically includes Styles instances that apply control themes for various product assemblies. While this simplifies the Application XAML, it can lead to a runtime exception when executing an application that uses the PublishAot project setting for Native AOT (Ahead-of-Time) support and hasn't been published with dotnet publish or an IDE's equivalent publish feature. See the Troubleshooting topic for details on how to statically include appropriate Styles instances, avoiding AOT errors.

Native Control Themes Setting

Native Avalonia controls must have themes applied or else an application window will render without most or all content being visible. Avalonia ships with the Simple and Fluent themes as built-in options. Actipro's theme also defines control themes for all native Avalonia controls and can be used in place of the Simple, Fluent, or other themes.

The ModernTheme.AreNativeControlThemesEnabled property determines if native Avalonia controls are themed using Actipro's themes.

The default value of this property is true, meaning native Avalonia control theming is enabled by default when using Actipro themes. Set the property to false to prevent this behavior.

Tip

See the Native Control Themes topic to learn more about Actipro's themes for native controls and the special styles and classes available.

No Native Control Themes Example

The following example shows how to use Avalonia's Simple theme for native Avalonia controls instead of Actipro's theming:

<Application ... xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui">
	<Application.Styles>

		<SimpleTheme />
		<actipro:ModernTheme AreNativeControlThemesEnabled="False" />

	</Application.Styles>
</Application>

Theme Definition Setting

The ModernTheme.Definition property can be set to a theme definition instance, which contains options for how theme resources will be generated. This property only needs to be set if you wish to customize how the options are used by the theme generator.

Setting the ModernTheme.Definition property will trigger the theme generator to refresh all theme resources. In the event you are not setting that property but are changing the options properties on the existing ThemeDefinition instance, the ModernTheme.RefreshResources method should be manually invoked afterward to force theme resource regeneration.

Accented Switches Example

The following example shows how to tell the theme to use accent colors for toggled switches by default, instead of using neutral colors. The accent color is also changed from the default blue hue to one based on the indigo hue.

<Application ...
	xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
	xmlns:generation="using:ActiproSoftware.UI.Avalonia.Themes.Generation">
	<Application.Styles>

		<actipro:ModernTheme>
			<actipro:ModernTheme.Definition>
				<generation:ThemeDefinition UseAccentedSwitches="True" AccentColorRampName="Indigo" />
			</actipro:ModernTheme.Definition>
		</actipro:ModernTheme>

	</Application.Styles>
</Application>

Tab Appearance Example

The following example shows how to tell the theme to render tabs using a Subtle appearance instead of Outline.

<Application ...
	xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui"
	xmlns:generation="using:ActiproSoftware.UI.Avalonia.Themes.Generation">
	<Application.Styles>

		<actipro:ModernTheme>
			<actipro:ModernTheme.Definition>
				<generation:ThemeDefinition TabAppearanceKind="Subtle" />
			</actipro:ModernTheme.Definition>
		</actipro:ModernTheme>

	</Application.Styles>
</Application>

Code-behind Example

A theme definition can also be configured in code-behind instead of XAML.

Important

When loaded, ModernTheme initializes resources with a default theme, so configuring the definition in code-behind will result in resources being generated twice during startup. See the Theme Definitions topic for details on how to create a custom definition in code that encapsulates the desired property values and can be assigned in XAML to prevent refreshing resources.

The ModernTheme should ideally still be initialized in XAML like shown in the examples above and repeated here:

<Application ... xmlns:actipro="http://schemas.actiprosoftware.com/avaloniaui">
	<Application.Styles>

		<actipro:ModernTheme />

	</Application.Styles>
</Application>

Then in the Application.Initialize() method, look up the ModernTheme instance, modify the appropriate properties, and refresh resources to apply the change.

public partial class App : Application {
	...

	public override void Initialize() {
		AvaloniaXamlLoader.Load(this);

		// Customize the theme definition
		if (ModernTheme.TryGetCurrent(out var modernTheme) && (modernTheme.Definition is not null)) {
			modernTheme.Definition.UseAccentedSwitches = true;
			modernTheme.Definition.AccentColorRampName = Hue.Orange.ToString();

			// Must manually refresh resources after changing definition properties
			modernTheme.RefreshResources();
		}
	}
}
Tip

There are an enormous number of options in theme definitions that can alter the generated theme. See the theme definitions topic to learn more about the available options.