As I wrote in my Avalonia Hello World (On Linux) article I’ve made more progress than just executing the canned auto-generated Hello World. I’ve actually been through their one official tutorial and then some. You can find it on their website here. It will walk you through the steps of making a simple proof of concept “To Do List” application which shows you all of the steps of creating a simple application, adding controls, creating reactive controls, and how the Avalonia System works. It has two paths. One for those using Visual Studio on Windows and another for those using the .NET Core command line tools. Since I’m sticking with the whole doing everything on Linux thing I’m using the latter.
The steps in the tutorial are actually pretty spot on. There were a few small hiccups, which I’ve initiated my first Avalonia-related Pull Request to fix. I’m going to go over the macroscopic steps at a very high level, linking to each of the stages in the main manual and only showing differences from it as necessary. The tutorial is self guided so there is no need to follow my links to follow along, I’m just providing them for reference to what I’m wirting about. Some of the differences I highlight will be corrected in the above pull request if it is accepted. However I’m attempting to use JetBrain’s Rider IDE for my IDE so there are a couple of extra steps for that which will persist beyond that PR.
The first step is to create the project, as listed on the first section. This step is pretty straight forward. Just like in the Hello World article above we are simply executing one command:
dotnet new avalonia.mvvm -o Todo -n Todo
Just like with the original this creates a full directory project file structure to allow you to start working with your Avalonia project:
└── Todo ├── App.xaml ├── App.xaml.cs ├── Assets │ └── avalonia-logo.ico ├── Models ├── nuget.config ├── Program.cs ├── Todo.csproj ├── ViewLocator.cs ├── ViewModels │ ├── MainWindowViewModel.cs │ └── ViewModelBase.cs └── Views ├── MainWindow.xaml └── MainWindow.xaml.cs
Create Solution and Open In Rider
An addendum to the first page is to create a solution and load it into Rider. We do this in three simple steps:
cd Todo dotnet new sln dotnet sln Todo.sln add Todo.csproj
First we jump down into the directory with our project. Next we tell dotnet to create a solution file in that directory. It will pick up the name Todo automatically so in the end you’ll have a Todo.sln file. However the CSPROJ project file won’t be added to it. We add it to the project with the last command. At this point we are now ready for Rider. Launch Rider and choose the
Open Solution or Project option if presented with the “Welcome to JetBrains Rider” screen or if it launches into a full window by choosing the
File -> Open -> Solution or Project... menu. Select the SLN file. Rider will then start reconstructing the project, pull in the NuGet dependencies and so on. Once the project is loaded you can now build it and run it. Build it the first time manually by choosing the
Build -> Build Solution menu option. You can then run by clicking the Run Icon or using the right-click menu on the project (highlighted in red below).
Create the TodoListView
The second part of the tutorial is where we start doing new stuff. We are creating our first new view which will hold our To Do List. You can find that tutorial section here. The instructions for this are pretty spot on however one thing is different than in the tutorial. The tutorial says that the created source files are going to have a namespace called Todo.Views. This is not correct. It should have that namespace but their example didn’t specify that so it uses the default. That name is
AvaloniaAppTemplate.Namespace. So for example in the TodoListView.xaml file the tutorial says it should look like this:
What is actually generated is:
It’s very subtle but it’s the last line of the
UserControl definition that reads
x:Class="AvaloniaAppTemplate.Namespace.TodoListView" that is wrong. It should read
x:Class="Todo.Views.TodoListView". In the
TodoListView.xaml file you will see the same string. This is something to remember whenever you are creating new controls through the dotnet tool. You will have to go through and replace the default template string with the actual namespace name. Everything else in this step is correct.
There is a way to correct this. The
dotnet new command has a
--namespace option. So to correct this problem without manually editing the files one can simply do:
dotnet new avalonia.usercontrol -o Views -n TodoListView --namespace Todo.Views
The remaining steps execute exactly as spelled out. To complete the exercise one:
- Creates a Model and View Model
- Wire up the Views and the View Models. This step actually has what appears to be magic happening as Avalonia “on its own” figures out how to map a View and View Model just by naming conventions. It’s more complicated than that and is extensible to use Dependency Injection and the like. The next section on locating views spells it out. I actually spent half an hour or so stuck in this step trying to figure it out and then when moving on to the next section had the tutorial explain for me what I had already discovered.
- Add the feature of being able to add items to the To Do list. This actually occupies two parts of the tutorial. The first is about prepping the new view. The Second is about wiring up the buttons and all of the data flows.
In the end you’ll have an app that has a list plus the ability to add items. I tested the code running on Windows as well as Linux and the results are pretty similar:
After all of that I have a pretty decent tutorial in the bag and a bunch of things I’ve learned about Avalonia. I was overall impressed with the project. That’s why I’m starting to contribute to working on documentation, became a monthly fiscal contributor, and am planning on using this for some desktop app projects that I’m looking forward to. Much of the manual was spot on. The changes that I created the pull request for should get it even closer. Some things are still rough around the edges, like the template. I have another blog post with deeper thoughts on Avalonia in general but so far this is the best .NET based truly cross platform system I have found yet. However overall it’s a big thumbs up for me.