A Cross-Platform GUI Theme for Desktop .NET Core Applications

Build beautiful user interfaces with AvaloniaUI

Artyom V. Gorchakov
May 7, 2020 · 5 min read
Graphical user interface components of Citrus.Avalonia — a style kit for cross-platform .NET Core applications. Available for Windows, Linux, and macOS.

valonia is a novel XAML UI framework, allowing .NET developers to deliver cross-platform .NET Core desktop applications for end-users. Inspired by Microsoft stack technologies, such as Xamarin Forms, Windows Presentation Framework, and Universal Windows Platform, Avalonia provides fully-featured means of building high-performant user interfaces of any complexity and any scale. Compared to Windows Presentation Framework, Universal Windows Platform, or Xamarin Forms, Avalonia provides a faster type-safe XAML compiler known as XamlIl, which makes the process of developing and debugging complex XAML interfaces far less painful. Moreover, XamlIl allows debugging XAML — watch this video on YouTube if you are still in doubt about giving Avalonia a try. Avalonia comes with ReactiveUI support out of the box, and this makes it possible to use the full power of reactive programming in an Avalonia .NET Core app.

Known Avalonia applications include its use in a cross-platform IDE and shell, in code editors, and in privacy-focused Bitcoin wallets. Avalonia is shipped as .NET Standard MIT-licensed NuGet packages and is available for free for anyone willing to build cross-platform desktop experiences in C# or F#, even for commercial use.

However, the ecosystem around the framework is still developing — there aren’t many GUI themes developed for the framework yet. Hence, designing a brand new modern style set seemed reasonable to me. User interface themes in Avalonia were designed as standalone components that can be easily replaced with any other sets of styles, and this made the development process of different color schemes even more simple and convenient.

XAML markup of Avalonia CSS-like styles attached to a Window.

The styling system in Avalonia can be thought of as a mix of CSS styling and WPF styling, a style consists of a selector and a collection of setters. Styles can be defined on any control, importing styles from files or packages is supported as well.

Avalonia styling system also supports pseudo-classes, which allows us to control the look of controls in different visual states. With the help of this feature, we can easily change the background of a button when a user presses it, or when a user moves the mouse over the control. Using the /template/ syntax, we can style the primitives based on which a more complex control is built. Dynamic and static resources are also supported, which may seem familiar for those coming from WPF, UWP, or Xamarin Forms.

XAML markup of TextBox template adjustment via a CSS-like pseudo-class and a dynamic brush.

Based on the mentioned implementation details, a novel graphical user interface theme was introduced and packed as a NuGet package. The theme received the name Citrus because of the orange accent color used in most of the color schemes available in the Citrus.Avalonia NuGet package. Following the licensing policy of the Avalonia framework, the Citrus theme is MIT-licensed and free for everyone, even for commercial use. The source code of the project is available on GitHub.

Getting Started

If you are completely new to Avalonia, see Avalonia Getting Started tutorial on their documentation website. After you have created the Avalonia .NET Core project, the Citrus.Avalonia package can be installed by either using the NuGet package manager GUI of any IDE, including JetBrains Rider and Microsoft Visual Studio. Another way is to execute the following .NET Core SDK command from your project root:

dotnet add package Citrus.Avalonia

Then, place the following XAML code into the App.xaml file:

<Application xmlns="https://github.com/avaloniaui"
<StyleInclude Source="avares://Citrus.Avalonia/Citrus.xaml"/>

The StyleInclude line is responsible for importing a set of styles into the application. The imported styles will be applied to all default XAML controls, descendant to the element which contains the StyleInclude line. As a result of the code snippet above, all default controls in your application will start using Citrus styles. If you are willing to apply the styles to a small part of your application, move the StyleInclude line to the Styles section of control other than Application . Notably, the Citrus NuGet package includes a dark color scheme as well.

Light (Citrus) and dark (Sea) themes included in Citrus.Avalonia NuGet package.

To browse the control gallery, clone the Citrus.Avalonia.Sandbox sample project. There are five color schemes total available inside the Citrus.Avalonia NuGet package, named Citrus, Sea, Rust, Candy, and Magma. In order to use color schemes other than the default one, you need to adjust the StyleInclude XAML tag by changing the Source attribute to point to another color scheme. To avoid collisions, remember to remove other StyleInclude lines present in the App.xaml file before.

To use different Citrus.Avalonia color schemes, comment out all <StyleInclude /> lines and uncomment one necessary line. Head over to README.md to copy-paste the contents shown in the picture.

Changing Color Schemes Dynamically

Dynamically changing color schemes in Citrus.Avalonia sandbox project.

In order to provide end-users the ability to change graphical user interface themes dynamically, move the StyleInclude line to a control other than Application . The StyleManager class shown below takes in a Window via the constructor, and provides the ability to change UI themes at runtime via the UseTheme method invocation.

StyleManager helper class, allowing to change themes which a Window uses dynamically at runtime.

See Avalonia Documentation for further details about building custom themes and adjusting styles. The source code of the Citrus theme described in this post may help as well, in case if you are going to build your own GUI theme. The sandbox project contains the control gallery shown in the pictures contained in this post. If you encounter any issues regarding the Avalonia GUI framework or the Citrus theme, head over to Avalonia Gitter. See the article Building Cross-Platform Reactive .NET Apps for more insight into the architecture used in XAML-based cross-platform C# applications.

Further work could cover more UI design guidelines. Folks from the Avalonia community have started working on the Material Design theme. Additionally, worth implementing the new Microsoft Fluent Design System and Apple Human Interface Guidelines.

The Startup

Get smarter at building your thing. Join The Startup’s +792K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Artyom V. Gorchakov

Written by

Full-stack developer, masters student, digital design enthusiast twitter.com/worldbeaterdev

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +792K followers.

Artyom V. Gorchakov

Written by

Full-stack developer, masters student, digital design enthusiast twitter.com/worldbeaterdev

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +792K followers.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store