Skip to content

Multiple Platforms

Tom Laird-McConnell edited this page Jan 22, 2025 · 1 revision

If you have an existing Avalonia multi-platform application it is easy to make it work as a Console app using Consolonia.

image

Add new Consolonia platform project

We want to create a Consolonia based project which represents running the application in console mode.

Step 1 - Add a Consolonia project to your solution.

NOTE: These instructions assume you have the Consolonia.Templates installed dotnet new install Consolonia.Templates

If you are following the naming pattern of HexView.Desktop, I recommend calling it HexView.Console

image

Step 2 - Add project reference to your shared assembly project

The new console project is the runtime host for your project. Just like any platform project (.Desktop, .Android, etc.) you need to add a project reference to your shared definitions so it can host them on the platform.

image

Step 3 - Derive from existing app in the shared project

We want to be able to define new console appropriate styles for the console application, but we also want all of the existing app definitions to be shared.

To do that we can simply change the App base class to be the existing Avalonia Application definition in the shared project.

The resulting app definition should look like this.

    public class App : HexView.App
    {
        public override void Initialize()
        {
            AvaloniaXamlLoader.Load(this);
        }
    }

Step 4 - Delete MainWindow from the new console project

We don't need a MainWindow in the new project, as the application we are using is defined in the shared project.

Making it work

At this point, you should be able to run the application. Odds are it won't look great, and may not even be functional.

There are 2 primary reasons for things not working:

  1. Layout is different for console character based applications
  2. There are features you are using which aren't supported on console applications.

Customize the layout for your console app

If you read up on the architecture you will know that the biggest difference between a GUI application and character based application is that all pixels equate to characters. The primary styling you need to do is to adjust your style to layout correctly using character based units.

This is pretty easy, it basically means wherever you have pixel based units you probably need to make sure they are changeable. Avalonia has powerful system for doing this either via static resources or styles:

  • StaticResources- Change your layout to bind to well-known static resources that are defined in your app.axaml
  • Styles - use Style Selectors to customize your layout

These styles can be defined in the Project.Console app.axaml so that they override the styles that you might have in the original app.axaml.

Here's an example of using static resources:

<Application.Resources>
  <x:Double x:Key="Spacing">1</x:Double>
  <Thickness x:Key="FullMargin">1,1,1,1</Thickness>
</Application.Resources>

With references:

   <Border BorderThickness="{StaticResource FullMargin}" BorderBrush="Black"...>

And here's an example using styles

<Application.Styles>
  <Style Selector="Border.card">
     <Setting Property="BorderThickness" Value="1,1,1,1"/>
   </Style>
</Application.Styles>

Assuming you have a class on the resource like this:

   <Border class="card" BorderBrush="Black"...>

Any markup which has hard coded pixel based units you will want to make are can be customized using a stylesheet

  • Margin, Padding, Width, Height, Spacing, BorderThickness, etc.

Dealing with features that are not supported.

Avalonia is very rich in its capabilities and Consolonia supports those features to the extent that it can, but there are just some things you can't do in a character based application.

For example: doing arbitrary transforms on elements (rotating and skewing text and line drawings, etc) are only possible with a pixel based interface.

Your application logic and behavior will need to be compatible with the constraints of the platform. The degree you can share code and layout and how you do that is entirely beyond the scope of a tutorial.