-
-
Notifications
You must be signed in to change notification settings - Fork 12
Multiple Platforms
If you have an existing Avalonia multi-platform application it is easy to make it work as a Console app using Consolonia.
We want to create a Consolonia based project which represents running the application in console mode.
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
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.
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);
}
}
We don't need a MainWindow in the new project, as the application we are using is defined in the shared project.
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:
- Layout is different for console character based applications
- There are features you are using which aren't supported on console applications.
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.
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.