xaml-csharp-development-skill-for-avalonia

Resources, Assets, Theme Variants, and XmlnsDefinition

Table of Contents

  1. Scope and APIs
  2. Resource Authoring and Lookup
  3. Runtime ResourceDictionary Mutation
  4. Deferred and Not-Shared Resource Entries
  5. Theme Variant Authoring and Runtime Behavior
  6. Dynamic Resources and Includes
  7. Asset Authoring and Access
  8. XmlnsDefinition Usage
  9. Best Practices
  10. Troubleshooting

Scope and APIs

Primary APIs:

Related XAML runtime resource APIs:

Related markup type-converter contracts (framework parsing layer):

Note:

Resource Authoring and Lookup

Layered strategy:

  1. Global resources (Application.Resources, Application.Styles).
  2. Feature/module dictionaries (MergedDictionaries).
  3. Control-local dictionaries only when scoping is intentional.

ResourceDictionary lookup behavior:

Example:

<ResourceDictionary>
  <Color x:Key="BrandColor">#0A84FF</Color>

  <ResourceDictionary.MergedDictionaries>
    <ResourceInclude Source="avares://MyApp/Styles/Buttons.axaml" />
  </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Runtime ResourceDictionary Mutation

ResourceDictionary is mutable and supports efficient runtime updates.

Useful members:

Pattern:

var resources = Application.Current!.Resources;

if (resources is ResourceDictionary dict)
{
    dict.EnsureCapacity(64);

    dict.SetItems(new[]
    {
        new KeyValuePair<object, object?>("SpacingM", 12d),
        new KeyValuePair<object, object?>("SpacingL", 16d)
    });

    if (!dict.ContainsKey("FeatureEnabled"))
        dict["FeatureEnabled"] = true;
}

Deferred and Not-Shared Resource Entries

For expensive or late materialization, use deferred APIs:

Guidance:

Theme Variant Authoring and Runtime Behavior

Theme variant APIs:

Use app-wide setting:

<Application RequestedThemeVariant="Default" />

Use local override scope:

<ThemeVariantScope RequestedThemeVariant="Dark">
  <ContentPresenter Content="{Binding}" />
</ThemeVariantScope>

Theme dictionaries:

<ResourceDictionary>
  <ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Light">
      <SolidColorBrush x:Key="AppBackground" Color="White" />
    </ResourceDictionary>
    <ResourceDictionary x:Key="Dark">
      <SolidColorBrush x:Key="AppBackground" Color="#202020" />
    </ResourceDictionary>
  </ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

Dynamic Resources and Includes

Use dynamic resources when runtime theme/resource changes should propagate automatically.

Key APIs:

Guidance:

Asset Authoring and Access

Project item guidance:

C# asset access:

using Avalonia.Platform;

using var stream = AssetLoader.Open(new Uri("avares://MyApp/Assets/logo.png"));

Additional APIs:

XmlnsDefinition Usage

XmlnsDefinitionAttribute maps XML namespace to CLR namespace at assembly level.

Pattern:

[assembly: XmlnsDefinition("https://github.com/avaloniaui", "MyApp.Controls")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "MyApp.Theming")]

Effect:

Best Practices

Troubleshooting

  1. Resource not found.
    • Key mismatch, dictionary not merged, or scope owner is wrong.
  2. Theme switch does not update value.
    • Missing ThemeDictionaries entry for active variant or missing DynamicResource usage.
  3. Deferred resource throws/re-enters unexpectedly.
    • Check AddDeferred factory side effects and avoid recursive same-key lookups.
  4. Include-based resources appear detached.
    • Verify Source URI and inspect ResourceInclude.Owner / StyleInclude.Owner transitions.
  5. XAML cannot resolve custom controls.
    • Verify assembly-level XmlnsDefinition mapping and public type visibility.
  6. Culture-tag strings fail to parse in custom markup extensions.
    • Verify the input is a valid IETF language tag expected by CultureInfoIetfLanguageTagConverter.