xaml-csharp-development-skill-for-avalonia

XAML in Libraries and Resource Packaging

Table of Contents

  1. Scope and APIs
  2. Packaging Rules for Library XAML
  3. URI Rules and Path Resolution
  4. Include Semantics (StyleInclude, ResourceInclude, MergeResourceInclude)
  5. Cross-Assembly Include Resolution
  6. XML Namespace Mapping for Library Controls
  7. Visibility and Reachability
  8. Recommended Library Layout
  9. Troubleshooting

Scope and APIs

Primary APIs and build parts:

Reference source files:

Packaging Rules for Library XAML

Library baseline:

By default, *.axaml and *.paml are discovered as AvaloniaXaml when default items are enabled.

During build:

URI Rules and Path Resolution

Canonical absolute form:

Supported relative include forms (resolved from current document URI):

In grouped runtime documents (LoadGroup), relative resolution depends on each document BaseUri.

Include Semantics (StyleInclude, ResourceInclude, MergeResourceInclude)

StyleInclude / ResourceInclude

When source is compile-resolvable (avares:// or relative URI), compiler group transforms replace include nodes with direct compiled references.

At runtime (dynamic path), includes can still load via AvaloniaXamlLoader.Load(...).

MergeResourceInclude

Special behavior:

If include shape/source is invalid, compiler reports transform diagnostics.

Cross-Assembly Include Resolution

For external assembly includes, compiler attempts:

  1. CompiledAvaloniaXaml.!AvaloniaResources public Build:<path> method,
  2. public type fallback (usually x:Class type) matching expected loaded type.

If neither exists or types mismatch, compile-time transform error is produced.

Implication for library authors:

XML Namespace Mapping for Library Controls

Expose controls with assembly attributes:

using Avalonia.Metadata;

[assembly: XmlnsDefinition("https://github.com/avaloniaui", "MyLibrary.Controls")]
[assembly: XmlnsPrefix("https://github.com/avaloniaui", "mylib")]

Then consumers can use:

xmlns:mylib="https://github.com/avaloniaui"

Visibility and Reachability

x:ClassModifier and CLR visibility matter:

Use non-public XAML classes only when you do not need runtime URI-based construction from other assemblies.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <EnableAvaloniaXamlCompilation>true</EnableAvaloniaXamlCompilation>
    <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
  </PropertyGroup>

  <ItemGroup>
    <AvaloniaXaml Include="Themes/**/*.axaml" />
    <AvaloniaResource Include="Assets/**" />
  </ItemGroup>
</Project>

Example consumer usage:

<Application.Styles>
  <StyleInclude Source="avares://MyLibrary/Themes/LibraryTheme.axaml" />
</Application.Styles>

Troubleshooting

  1. Include cannot resolve external file
    • Wrong assembly name/path in avares://... URI.
  2. Relative include fails in runtime grouping
    • Missing BaseUri on documents.
  3. Merge include errors
    • Target is not a ResourceDictionary, or order/source is invalid.
  4. Library controls not visible in XAML
    • Missing XmlnsDefinition mapping or incorrect CLR namespace.
  5. URI runtime loading cannot construct type
    • Resource/type not publicly reachable for dispatcher path.