Add full XAML support for .NET MAUI compatibility

New features:
- MauiAppBuilderExtensions.UseOpenMauiLinux() for standard MAUI integration
- New template: openmaui-linux-xaml with full XAML support
- Standard MAUI XAML syntax (ContentPage, VerticalStackLayout, etc.)
- Resource dictionaries (Colors.xaml, Styles.xaml)
- Compiled XAML support via MauiXaml items

Templates now available:
- dotnet new openmaui-linux      (code-based UI)
- dotnet new openmaui-linux-xaml (XAML-based UI)

Usage:
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .UseOpenMauiLinux();  // Enable Linux with XAML
This commit is contained in:
logikonline
2025-12-19 05:17:50 -05:00
parent ae5c9ab738
commit 1d9338d823
15 changed files with 646 additions and 7 deletions

View File

@@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "MarketAlly LLC",
"classifications": ["MAUI", "Linux", "Desktop", "App", "OpenMaui", "XAML"],
"identity": "OpenMaui.Linux.XamlApp",
"name": "OpenMaui Linux XAML Application",
"shortName": "openmaui-linux-xaml",
"description": "A .NET MAUI application for Linux using standard XAML syntax with OpenMaui platform support.",
"tags": {
"language": "C#",
"type": "project"
},
"sourceName": "OpenMauiXamlApp",
"preferNameDirectory": true,
"symbols": {
"Framework": {
"type": "parameter",
"description": "The target framework for the project.",
"datatype": "choice",
"choices": [
{
"choice": "net9.0",
"description": "Target .NET 9.0"
}
],
"defaultValue": "net9.0",
"replaces": "net9.0"
}
},
"primaryOutputs": [
{ "path": "OpenMauiXamlApp.csproj" }
],
"postActions": [
{
"description": "Restore NuGet packages required by this project.",
"manualInstructions": [{ "text": "Run 'dotnet restore'" }],
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
"continueOnError": true
}
]
}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="OpenMauiXamlApp.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,10 @@
namespace OpenMauiXamlApp;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MainPage();
}
}

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="OpenMauiXamlApp.MainPage"
Title="Home">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25"
VerticalOptions="Center">
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot waving hi to you!" />
<Label
Text="Hello, OpenMaui!"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1"
HorizontalOptions="Center" />
<Label
Text="Welcome to .NET MAUI on Linux"
Style="{StaticResource SubHeadline}"
SemanticProperties.Description="Welcome to dot net MAUI on Linux"
HorizontalOptions="Center" />
<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill" />
<HorizontalStackLayout
Spacing="10"
HorizontalOptions="Center">
<CheckBox
x:Name="AgreeCheckBox"
IsChecked="False" />
<Label
Text="I agree to the terms"
VerticalOptions="Center" />
</HorizontalStackLayout>
<Entry
x:Name="NameEntry"
Placeholder="Enter your name"
HorizontalOptions="Fill" />
<Slider
x:Name="VolumeSlider"
Minimum="0"
Maximum="100"
Value="50"
HorizontalOptions="Fill" />
<Label
x:Name="VolumeLabel"
Text="Volume: 50"
HorizontalOptions="Center" />
<Switch
x:Name="DarkModeSwitch"
IsToggled="False"
HorizontalOptions="Center" />
<ProgressBar
x:Name="LoadingProgress"
Progress="0.5"
ProgressColor="{StaticResource Primary}"
HorizontalOptions="Fill" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>

View File

@@ -0,0 +1,30 @@
namespace OpenMauiXamlApp;
public partial class MainPage : ContentPage
{
private int _count = 0;
public MainPage()
{
InitializeComponent();
// Wire up slider value changed
VolumeSlider.ValueChanged += OnVolumeChanged;
}
private void OnCounterClicked(object sender, EventArgs e)
{
_count++;
CounterBtn.Text = _count == 1
? $"Clicked {_count} time"
: $"Clicked {_count} times";
SemanticScreenReader.Announce(CounterBtn.Text);
}
private void OnVolumeChanged(object? sender, ValueChangedEventArgs e)
{
VolumeLabel.Text = $"Volume: {e.NewValue:F0}";
}
}

View File

@@ -0,0 +1,24 @@
using Microsoft.Maui.Controls.Hosting;
using Microsoft.Maui.Hosting;
using OpenMaui.Platform.Linux.Hosting;
namespace OpenMauiXamlApp;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseOpenMauiLinux() // Enable Linux platform with full XAML support
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
return builder.Build();
}
}

View File

@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<OutputType>Exe</OutputType>
<RootNamespace>OpenMauiXamlApp</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Enable XAML compilation -->
<EnableDefaultXamlItems>true</EnableDefaultXamlItems>
<!-- Linux Runtime -->
<RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<!-- OpenMaui Linux Platform -->
<PackageReference Include="OpenMaui.Controls.Linux" Version="1.0.0-preview.*" />
<!-- Core MAUI packages (includes XAML support) -->
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.*" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.*" />
</ItemGroup>
<!-- XAML Files -->
<ItemGroup>
<MauiXaml Update="**/*.xaml" />
<MauiXaml Update="App.xaml" />
<MauiXaml Update="MainPage.xaml" />
</ItemGroup>
<!-- Embedded Resources -->
<ItemGroup>
<EmbeddedResource Include="Resources\**\*" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,16 @@
using OpenMaui.Platform.Linux;
namespace OpenMauiXamlApp;
public class Program
{
public static void Main(string[] args)
{
// Create the MAUI app using standard MAUI bootstrapping
var app = MauiProgram.CreateMauiApp();
// Run with Linux platform
// This connects MAUI's virtual views to our Skia platform views
LinuxApplication.Run(app);
}
}

View File

@@ -0,0 +1,4 @@
# Add your fonts here
# Recommended:
# - OpenSans-Regular.ttf
# - OpenSans-Semibold.ttf

View File

@@ -0,0 +1,2 @@
# Add your images here
# Required: dotnet_bot.png (from MAUI template)

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xaml-comp compile="true" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<!-- Primary Colors -->
<Color x:Key="Primary">#512BD4</Color>
<Color x:Key="PrimaryDark">#3B1F9E</Color>
<Color x:Key="PrimaryLight">#7B5EDF</Color>
<!-- Secondary Colors -->
<Color x:Key="Secondary">#DFD8F7</Color>
<Color x:Key="SecondaryDark">#9880E5</Color>
<!-- Accent Colors -->
<Color x:Key="Accent">#FF6B35</Color>
<!-- Neutral Colors -->
<Color x:Key="White">White</Color>
<Color x:Key="Black">Black</Color>
<Color x:Key="Gray100">#E1E1E1</Color>
<Color x:Key="Gray200">#C8C8C8</Color>
<Color x:Key="Gray300">#ACACAC</Color>
<Color x:Key="Gray400">#919191</Color>
<Color x:Key="Gray500">#6E6E6E</Color>
<Color x:Key="Gray600">#404040</Color>
<Color x:Key="Gray900">#212121</Color>
<Color x:Key="Gray950">#141414</Color>
<!-- Semantic Colors -->
<Color x:Key="Success">#4CAF50</Color>
<Color x:Key="Warning">#FF9800</Color>
<Color x:Key="Error">#F44336</Color>
<Color x:Key="Info">#2196F3</Color>
<!-- Light Theme -->
<Color x:Key="LightBackground">White</Color>
<Color x:Key="LightSurface">#F5F5F5</Color>
<Color x:Key="LightOnBackground">#212121</Color>
<Color x:Key="LightOnSurface">#424242</Color>
<!-- Dark Theme -->
<Color x:Key="DarkBackground">#121212</Color>
<Color x:Key="DarkSurface">#1E1E1E</Color>
<Color x:Key="DarkOnBackground">#FFFFFF</Color>
<Color x:Key="DarkOnSurface">#E0E0E0</Color>
</ResourceDictionary>

View File

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xaml-comp compile="true" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<!-- Headline Style -->
<Style x:Key="Headline" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource Primary}" />
<Setter Property="FontSize" Value="32" />
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
<!-- SubHeadline Style -->
<Style x:Key="SubHeadline" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource Gray500}" />
<Setter Property="FontSize" Value="18" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
<!-- Default Button Style -->
<Style TargetType="Button">
<Setter Property="TextColor" Value="White" />
<Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Padding" Value="14,10" />
<Setter Property="MinimumHeightRequest" Value="44" />
<Setter Property="MinimumWidthRequest" Value="44" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="TextColor" Value="{StaticResource Gray300}" />
<Setter Property="BackgroundColor" Value="{StaticResource Gray100}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource PrimaryDark}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<!-- Default Entry Style -->
<Style TargetType="Entry">
<Setter Property="TextColor" Value="{StaticResource Gray900}" />
<Setter Property="PlaceholderColor" Value="{StaticResource Gray400}" />
<Setter Property="BackgroundColor" Value="Transparent" />
<Setter Property="FontSize" Value="14" />
<Setter Property="MinimumHeightRequest" Value="44" />
</Style>
<!-- Default Label Style -->
<Style TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource Gray900}" />
<Setter Property="FontSize" Value="14" />
</Style>
<!-- Default CheckBox Style -->
<Style TargetType="CheckBox">
<Setter Property="Color" Value="{StaticResource Primary}" />
</Style>
<!-- Default Switch Style -->
<Style TargetType="Switch">
<Setter Property="OnColor" Value="{StaticResource Primary}" />
<Setter Property="ThumbColor" Value="White" />
</Style>
<!-- Default Slider Style -->
<Style TargetType="Slider">
<Setter Property="MinimumTrackColor" Value="{StaticResource Primary}" />
<Setter Property="MaximumTrackColor" Value="{StaticResource Gray200}" />
<Setter Property="ThumbColor" Value="{StaticResource Primary}" />
</Style>
<!-- Default ProgressBar Style -->
<Style TargetType="ProgressBar">
<Setter Property="ProgressColor" Value="{StaticResource Primary}" />
</Style>
<!-- Default ActivityIndicator Style -->
<Style TargetType="ActivityIndicator">
<Setter Property="Color" Value="{StaticResource Primary}" />
</Style>
<!-- Page Background -->
<Style TargetType="Page" ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="{StaticResource LightBackground}" />
</Style>
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor" Value="{StaticResource LightBackground}" />
</Style>
</ResourceDictionary>