VOOZH about

URL: https://thenewstack.io/avalonia-an-open-source-option-for-cross-platform-ui-work/

⇱ Avalonia: An Open Source Option for Cross-Platform UI Work - The New Stack


TNS
SUBSCRIBE
Join our community of software engineering leaders and aspirational developers. Always stay in-the-know by getting the most important news and exclusive content delivered fresh to your inbox to learn more about at-scale software development.
REQUIRED
It seems that you've previously unsubscribed from our newsletter in the past. Click the button below to open the re-subscribe form in a new tab. When you're done, simply close that tab and continue with this form to complete your subscription.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.
Welcome and thank you for joining The New Stack community!
Please answer a few simple questions to help us deliver the news and resources you are interested in.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Great to meet you!
Tell us a bit about your job so we can cover the topics you find most relevant.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Welcome!

We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.

What’s next?

Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.

Follow TNS on your favorite social media networks.

Become a TNS follower on LinkedIn.

Check out the latest featured and trending stories while you wait for your first TNS newsletter.

PREV
1 of 2
NEXT
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
Thanks for your opinion! Subscribe below to get the final results, published exclusively in our TNS Update newsletter:
NEW! Try Stackie AI
From clobbered drafts to real-time sync
Apr 14th 2026 10:00am, by David Moore
TypeScript 6.0 RC arrives as a bridge to a faster future
Mar 14th 2026 9:00am, by Darryl K. Taft
Mastra empowers web devs to build AI agents in TypeScript
Jan 28th 2026 11:00am, by Loraine Lawson
2025-01-21 08:33:12
Avalonia: An Open Source Option for Cross-Platform UI Work
tutorial,
Developer tools / Frontend Development

Avalonia: An Open Source Option for Cross-Platform UI Work

Avalonia is an open source framework for cross-platform UI work. It's commonly used for building apps in .NET that work across devices.
Jan 21st, 2025 8:33am by David Eastman
👁 Featued image for: Avalonia: An Open Source Option for Cross-Platform UI Work
Image via Unsplash+. 
The problem with .NET has always been that Microsoft were somewhat slow to embrace non-Windows systems. To find a UI library that uses C# but runs on a MacBook is harder than it should be. One solution is Avalonia, which helps you “build apps for every device using .NET” — and it does indeed fill the open source cross-platform framework hole. Plus, looking at it will also hone your framework design skills.

Getting Started

So let’s get started with Avalonia by writing something simple, while having a look at the architecture. I’ll assume you have Visual Studio Code installed, as well as .NET. I’ve covered using VS Code in various earlier posts; its flexibility makes it ideal for dipping into different projects (Avalonia itself actually recommends using JetBrains’ .NET IDE, Rider). We’ll use dotnet in the command line and that will speed up creating a simple project. Firstly, we install the Avalonia templates: 👁 Image
In a fresh project directory, we use the MVVM template, which also works on MacOS: 👁 Image
Then we’ll open up with Visual Studio Code in the folder as always: 👁 Image
Search for the Avalonia extensions. You will certainly want the first one: 👁 Image
If we select the Program.cs file and click the arrow to “Run the program associated with this file” Avalonia will immediately build a window: 👁 Image
That’s fine. Now let’s take a look at the basics and then do something more interesting. If you are familiar with Windows Presentation Foundation (or WPF, which I happily assume you know nothing about) then you will have seen Extensible Application Markup Language (XAML) and Avalonia uses its own branded “axaml” file extension. You’ll also note that it appends the C# extension to mark “code behind” files. This all works, even if it is a little messy. Yes, it’s XML folks. Thankfully, there are a few interesting files. The window is defined in “MainWindow.axaml”, and you can see the Title defined: 👁 Image
The only other interesting thing is the TextBlock definition.
<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
Apart from positioning itself in the center of the screen, as we saw, it also introduces us to data binding, which is slightly trickier than perhaps it should be. Clearly, we are going to find that the term Greeting is bound to a variable, but where? If we look into one of the boilerplate files “App.axaml.cs”, we see that there is a thing called DataContext, which gets set on startup:
...
desktop.MainWindow = new MainWindow { 
 DataContext = new MainWindowViewModel(), 
};
...

This states that when the framework starts binding, it will use this new model class. And if we look in “MainWindowViewModel.cs”, we find roughly what we were expecting:
namespace avaloniaui.ViewModels; 

public partial class MainWindowViewModel : ViewModelBase { 
 public string Greeting { get; } = "Welcome to Avalonia!"; 
}
So, the TextBlock has been bound to the class variable. The IDE is mainly helpful in negotiating this after a build. S,o let’s hit the hard stuff and look at a bit of UI. I’m going to build a list box that allows you to select a simple category item and fill another list with examples. So we’ll see a bit of UI design and deal with some events. Going back into the MainWindow.axaml file, we replace the solitary TextBlock with this:
<StackPanel Orientation="Horizontal"> 
 <TextBlock Text="{Binding Greeting}" FontSize="20" FontWeight="Bold" Margin="20 10"/>
 <StackPanel Margin="20 25">
 <TextBlock Margin="0 5" Background="LightBlue" DockPanel.Dock="Top">Choose a category</TextBlock>
 <ListBox x:Name="category" SelectionChanged="CategoryChanged" Margin="1" SelectionMode="Single,AlwaysSelected">
 <ListBox.ItemTemplate>
 <DataTemplate>
 <TextBlock Text="{Binding}"/>
 </DataTemplate>
 </ListBox.ItemTemplate>
 </ListBox>
 </StackPanel>

 <StackPanel Margin="20 25">
 <TextBlock Margin="0 5" Background="LightBlue" DockPanel.Dock="Top">Examples</TextBlock>
 <ListBox x:Name="resultlist">
 <ListBox.ItemTemplate>
 <DataTemplate>
 <TextBlock Text="{Binding}"/>
 </DataTemplate>
 </ListBox.ItemTemplate>
 </ListBox>
 </StackPanel>
</StackPanel>
Boom. Looking only at the tags, you can see we are using a StackPanel as an overall container, with two StackPanels inside — as we’ve defined the outer one as horizontal, the inner ones will sit next to each other. We define a ListBox in both stacks. One behavior difference is that the SelectionMode of the first forces something to always be selected. From a data point of view, we have named the first List box “category” and the second one “resultlist” which will be relevant later. And you can see the TextBlock within each stack has a binding. So we will be putting our own strings in it. Also, of course, right now we have no data. Event-wise, we are detecting “SelectionChanged” in the first stack. We will need to respond to that. Indeed, if we try running this, we will be told by Avalonia that it is “Unable to find suitable setter or adder for property SelectionChanged”. So let’s try and fix the events. Inside the MainWindow class, we add the method:
using System; 
... 
public void CategoryChanged(object source, SelectionChangedEventArgs args) { 
 if (source is ListBox listBox) { 
 Console.WriteLine($"Category changed to {listBox.SelectedItem}"); 
 } 
}
We can now run the framework again, and we even get the Stack column text titles: 👁 Image
Let’s try adding some data. We can actually just work in the MainWindow class. We’ll add some data and use it to fill the first ListBox and present it as the ItemSource for the category ListBox:
using System.Collections.Generic;
...

private Dictionary<string, List<string>> catgeoryDict = new Dictionary<string, List<string>>()
{
 {"Trees", new List<string>(){"Larch", "Oak", "Pine", "Willow"}},
 {"Birds", new List<string>(){"Eagle", "Hawk", "Owl", "Raven"}},
 {"Mammals", new List<string>(){ "Bear", "Deer", "Fox", "Wolf"}},
 {"Snakes", new List<string>(){"Cobra", "Python", "Rattlesnake", "Viper"}},
 {"Insects", new List<string>(){"Ant", "Bee", "Fly", "Wasp"}}
};
public MainWindow()
{
 InitializeComponent();
 category.ItemsSource = new List<string>(catgeoryDict.Keys);
}
This gives us a nice category ListBox. So we are half done. 👁 Image
Now, all we need to do is to respond to the category change when a user hits a selection by filling in the right list with examples from our data. We just add one line to the event response method:
public void CategoryChanged(object source, SelectionChangedEventArgs args)
{
 if (source is ListBox listBox)
 {
 Console.WriteLine($"Category changed to {listBox.SelectedItem}");
 resultlist.ItemsSource = catgeoryDict[(string)listBox.SelectedItem].ToList();
 }
}
As the SelectedItem is a string in our case, we can just use it as the index into the category dictionary to find the examples. Now we are done. We can select any of the categories and put the result in the next listbox: 👁 Image

Conclusion

That wasn’t too painful, but anything further would need us to use the ViewModel correctly. I tried using the DataGrid, a more powerful component to display data, and that was much more finicky. For brevity, there is quite a bit left unexplained, even for this simple example — this feels like quite a bit of design baggage from elsewhere. Nevertheless, it successfully serves its purpose as an open source option for cross-platform UI work.
TRENDING STORIES
David has been a London-based professional software developer with Oracle Corp. and British Telecom, and a consultant helping teams work in a more agile fashion. He wrote a book on UI design and has been writing technical articles ever since....
Read more from David Eastman
SHARE THIS STORY
TRENDING STORIES
SHARE THIS STORY
TRENDING STORIES
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.