diff --git a/StabilityMatrix.Avalonia/App.axaml b/StabilityMatrix.Avalonia/App.axaml
new file mode 100644
index 00000000..822dc1e9
--- /dev/null
+++ b/StabilityMatrix.Avalonia/App.axaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/StabilityMatrix.Avalonia/App.axaml.cs b/StabilityMatrix.Avalonia/App.axaml.cs
new file mode 100644
index 00000000..803687e4
--- /dev/null
+++ b/StabilityMatrix.Avalonia/App.axaml.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
+using Microsoft.Extensions.DependencyInjection;
+using StabilityMatrix.Avalonia.ViewModels;
+using StabilityMatrix.Avalonia.Views;
+
+namespace StabilityMatrix.Avalonia;
+
+public partial class App : Application
+{
+ public static IServiceProvider Services { get; set; } = null!;
+
+
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+
+ // Set design theme
+ if (Design.IsDesignMode)
+ {
+ RequestedThemeVariant = ThemeVariant.Dark;
+ }
+ }
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ ConfigureServiceProvider();
+
+ var mainViewModel = Services.GetRequiredService();
+
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ {
+ desktop.MainWindow = new MainWindow
+ {
+ DataContext = mainViewModel
+ };
+ }
+
+ base.OnFrameworkInitializationCompleted();
+ }
+
+ private static void ConfigureServiceProvider()
+ {
+ var services = ConfigureServices();
+ Services = services.BuildServiceProvider();
+ }
+
+ private static IServiceCollection ConfigureServices()
+ {
+ var services = new ServiceCollection();
+
+ services.AddSingleton();
+ services.AddSingleton();
+
+ services.AddTransient();
+
+ return services;
+ }
+}
diff --git a/StabilityMatrix.Avalonia/Assets/avalonia-logo.ico b/StabilityMatrix.Avalonia/Assets/avalonia-logo.ico
new file mode 100644
index 00000000..da8d49ff
Binary files /dev/null and b/StabilityMatrix.Avalonia/Assets/avalonia-logo.ico differ
diff --git a/StabilityMatrix.Avalonia/Program.cs b/StabilityMatrix.Avalonia/Program.cs
new file mode 100644
index 00000000..35ce2c2a
--- /dev/null
+++ b/StabilityMatrix.Avalonia/Program.cs
@@ -0,0 +1,24 @@
+using Avalonia;
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace StabilityMatrix.Avalonia;
+
+[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+public class Program
+{
+ // Initialization code. Don't use any Avalonia, third-party APIs or any
+ // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
+ // yet and stuff might break.
+ [STAThread]
+ public static void Main(string[] args) => BuildAvaloniaApp()
+ .StartWithClassicDesktopLifetime(args);
+
+ // Avalonia configuration, don't remove; also used by visual designer.
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UsePlatformDetect()
+ .WithInterFont()
+ .LogToTrace();
+}
diff --git a/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj b/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj
new file mode 100644
index 00000000..25f7c08c
--- /dev/null
+++ b/StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj
@@ -0,0 +1,28 @@
+
+
+ WinExe
+ net7.0
+ enable
+ true
+ app.manifest
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/StabilityMatrix.Avalonia/ViewLocator.cs b/StabilityMatrix.Avalonia/ViewLocator.cs
new file mode 100644
index 00000000..1e98f2c5
--- /dev/null
+++ b/StabilityMatrix.Avalonia/ViewLocator.cs
@@ -0,0 +1,34 @@
+using System;
+using Avalonia.Controls;
+using Avalonia.Controls.Templates;
+using StabilityMatrix.Avalonia.ViewModels;
+
+namespace StabilityMatrix.Avalonia;
+
+public class ViewLocator : IDataTemplate
+{
+ public Control Build(object? data)
+ {
+ if (data is null) throw new ArgumentNullException(nameof(data));
+
+ var name = data.GetType().FullName!.Replace("ViewModel", "View");
+ var type = Type.GetType(name);
+
+ // Get from DI
+ if (type is not null)
+ {
+ var view = App.Services.GetService(type);
+ if (view is not null)
+ {
+ return (Control) view;
+ }
+ }
+
+ return new TextBlock {Text = "Not Found: " + name};
+ }
+
+ public bool Match(object? data)
+ {
+ return data is ViewModelBase;
+ }
+}
diff --git a/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs
new file mode 100644
index 00000000..4224216d
--- /dev/null
+++ b/StabilityMatrix.Avalonia/ViewModels/LaunchPageViewModel.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace StabilityMatrix.Avalonia.ViewModels;
+
+public partial class LaunchPageViewModel : PageViewModelBase
+{
+ ///
+ /// The Title of this page
+ ///
+ public string Title => "Welcome to our Wizard-Sample.";
+
+ ///
+ /// The content of this page
+ ///
+ public string Message => "Press \"Next\" to register yourself.";
+
+ public override bool CanNavigateNext { get; protected set; }
+ public override bool CanNavigatePrevious { get; protected set; }
+}
diff --git a/StabilityMatrix.Avalonia/ViewModels/MainWindowViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/MainWindowViewModel.cs
new file mode 100644
index 00000000..dd4de726
--- /dev/null
+++ b/StabilityMatrix.Avalonia/ViewModels/MainWindowViewModel.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using Avalonia.Controls;
+using CommunityToolkit.Mvvm.ComponentModel;
+
+namespace StabilityMatrix.Avalonia.ViewModels;
+
+public partial class MainWindowViewModel : ViewModelBase
+{
+ public string Greeting => "Welcome to Avalonia!";
+
+ [ObservableProperty]
+ private PageViewModelBase? currentPage;
+
+ public List Pages { get; } = new();
+
+ public MainWindowViewModel(LaunchPageViewModel launchPageViewModel)
+ {
+ Pages.Add(launchPageViewModel);
+ CurrentPage = Pages[0];
+ }
+
+ public MainWindowViewModel()
+ {
+ if (!Design.IsDesignMode)
+ {
+ throw new InvalidOperationException("Default Constructor is only for design-time.");
+ }
+ Pages.Add(new LaunchPageViewModel());
+ CurrentPage = Pages[0];
+ }
+}
diff --git a/StabilityMatrix.Avalonia/ViewModels/PageViewModelBase.cs b/StabilityMatrix.Avalonia/ViewModels/PageViewModelBase.cs
new file mode 100644
index 00000000..896069c8
--- /dev/null
+++ b/StabilityMatrix.Avalonia/ViewModels/PageViewModelBase.cs
@@ -0,0 +1,17 @@
+namespace StabilityMatrix.Avalonia.ViewModels;
+
+///
+/// An abstract class for enabling page navigation.
+///
+public abstract class PageViewModelBase : ViewModelBase
+{
+ ///
+ /// Gets if the user can navigate to the next page
+ ///
+ public abstract bool CanNavigateNext { get; protected set; }
+
+ ///
+ /// Gets if the user can navigate to the previous page
+ ///
+ public abstract bool CanNavigatePrevious { get; protected set; }
+}
diff --git a/StabilityMatrix.Avalonia/ViewModels/SecondPageViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/SecondPageViewModel.cs
new file mode 100644
index 00000000..97bab672
--- /dev/null
+++ b/StabilityMatrix.Avalonia/ViewModels/SecondPageViewModel.cs
@@ -0,0 +1,27 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using CommunityToolkit.Mvvm.ComponentModel;
+
+namespace StabilityMatrix.Avalonia.ViewModels;
+
+///
+/// This is our ViewModel for the second page
+///
+partial class SecondPageViewModel : PageViewModelBase
+{
+ public SecondPageViewModel()
+ {
+ }
+
+ [Required]
+ [EmailAddress]
+ [ObservableProperty]
+ private string? mailAddress;
+
+ [Required]
+ [ObservableProperty]
+ private string? password;
+
+ public override bool CanNavigateNext { get; protected set; } = true;
+ public override bool CanNavigatePrevious { get; protected set; }
+}
diff --git a/StabilityMatrix.Avalonia/ViewModels/ViewModelBase.cs b/StabilityMatrix.Avalonia/ViewModels/ViewModelBase.cs
new file mode 100644
index 00000000..1828b85d
--- /dev/null
+++ b/StabilityMatrix.Avalonia/ViewModels/ViewModelBase.cs
@@ -0,0 +1,7 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+
+namespace StabilityMatrix.Avalonia.ViewModels;
+
+public class ViewModelBase : ObservableValidator
+{
+}
diff --git a/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml b/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml
new file mode 100644
index 00000000..e0f45b54
--- /dev/null
+++ b/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml.cs b/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml.cs
new file mode 100644
index 00000000..289e1096
--- /dev/null
+++ b/StabilityMatrix.Avalonia/Views/LaunchPageView.axaml.cs
@@ -0,0 +1,18 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace StabilityMatrix.Avalonia.Views;
+
+public partial class LaunchPageView : UserControl
+{
+ public LaunchPageView()
+ {
+ InitializeComponent();
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+}
diff --git a/StabilityMatrix.Avalonia/Views/MainWindow.axaml b/StabilityMatrix.Avalonia/Views/MainWindow.axaml
new file mode 100644
index 00000000..302c6f04
--- /dev/null
+++ b/StabilityMatrix.Avalonia/Views/MainWindow.axaml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/StabilityMatrix.Avalonia/Views/MainWindow.axaml.cs b/StabilityMatrix.Avalonia/Views/MainWindow.axaml.cs
new file mode 100644
index 00000000..fb0abbdf
--- /dev/null
+++ b/StabilityMatrix.Avalonia/Views/MainWindow.axaml.cs
@@ -0,0 +1,12 @@
+using Avalonia.Controls;
+using StabilityMatrix.Avalonia.ViewModels;
+
+namespace StabilityMatrix.Avalonia.Views;
+
+public partial class MainWindow : Window
+{
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/StabilityMatrix.Avalonia/app.manifest b/StabilityMatrix.Avalonia/app.manifest
new file mode 100644
index 00000000..def2d4b0
--- /dev/null
+++ b/StabilityMatrix.Avalonia/app.manifest
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+