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.
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 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.