Skip to main content

Overview

Avalonia provides powerful debugging capabilities including built-in DevTools, IDE integration, and platform-specific debugging options. This guide covers the essential debugging techniques for Avalonia applications.

Avalonia DevTools

Avalonia includes built-in developer tools similar to browser DevTools, providing visual tree inspection, property viewing, and performance monitoring.

Enabling DevTools

Add DevTools to your application in Program.cs:
public static AppBuilder BuildAvaloniaApp()
    => AppBuilder.Configure<App>()
        .UsePlatformDetect()
        .WithInterFont()
        .WithDeveloperTools()  // Add this line
        .LogToTrace();

Opening DevTools

Once enabled, press F12 while your application is running to open the DevTools window.

DevTools Features

Browse the live visual tree of your application, similar to browser element inspection. Click on elements to see their properties, styles, and data context.
  • Navigate parent-child relationships
  • View applied styles and templates
  • Inspect attached properties
  • Monitor property changes in real-time
View and modify property values at runtime:
  • Edit any property on selected elements
  • See inherited and local values
  • Test different property values without recompiling
  • Track property value sources (styles, bindings, local values)
Track routed events as they bubble and tunnel through the visual tree:
  • View event routing paths
  • Inspect event arguments
  • Monitor event timing
  • Debug event handling issues
Monitor rendering performance and identify bottlenecks:
  • Frame rate monitoring
  • Layout passes
  • Render time
  • Memory usage

IDE Debugging

Visual Studio

Setup

  1. Install the Avalonia for Visual Studio extension
  2. Open your Avalonia solution
  3. Set breakpoints in your code
  4. Press F5 to start debugging

XAML Designer

The Visual Studio extension provides a XAML previewer:
  • Real-time preview of AXAML files
  • Design-time data context
  • IntelliSense support
  • Error highlighting

Troubleshooting Visual Studio

Manually build the Avalonia.Build.Tasks project at least once, or build the solution with Nuke:
nuke --target Compile --configuration Release

JetBrains Rider

JetBrains Rider provides excellent built-in support for Avalonia.

Features

  • Code completion for AXAML
  • Inspections and refactorings
  • XAML previewer (via AvaloniaRider plugin)
  • Full debugging support

Install XAML Previewer

  1. Go to SettingsPluginsMarketplace
  2. Add plugin repository: https://plugins.jetbrains.com/plugins/dev/14839
  3. Search for and install AvaloniaRider
  4. Restart Rider

Debugging

  1. Set breakpoints by clicking in the gutter
  2. Press F5 or click the Debug button
  3. Use the debugger toolbar to step through code

VS Code

Use VS Code with the C# extension for debugging:
  1. Install C# extension
  2. Install Avalonia for VS Code
  3. Open your project folder
  4. Press F5 to start debugging

Logging and Diagnostics

Enable Trace Logging

Avalonia uses System.Diagnostics.Trace for logging. Enable it in your application:
public static AppBuilder BuildAvaloniaApp()
    => AppBuilder.Configure<App>()
        .UsePlatformDetect()
        .WithInterFont()
        .LogToTrace()  // Enable trace logging
        .WithDeveloperTools();

Configure Log Verbosity

Control logging levels through environment variables or configuration:
using Avalonia.Logging;

Logger.Sink = new ConsoleSink
{
    Level = LogEventLevel.Debug
};

Custom Logging

Implement custom logging for diagnostic purposes:
using Avalonia.Logging;

public class FileLogSink : ILogSink
{
    private readonly StreamWriter _writer;

    public FileLogSink(string logPath)
    {
        _writer = new StreamWriter(logPath, append: true);
    }

    public bool IsEnabled(LogEventLevel level, string area)
    {
        return level >= LogEventLevel.Warning;
    }

    public void Log(LogEventLevel level, string area, object source, string messageTemplate)
    {
        _writer.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{level}] {area}: {messageTemplate}");
        _writer.Flush();
    }

    public void Log<T0>(LogEventLevel level, string area, object source, string messageTemplate, T0 propertyValue0)
    {
        Log(level, area, source, string.Format(messageTemplate, propertyValue0));
    }

    // Implement other overloads...
}

// Use in Program.cs
Logger.Sink = new FileLogSink("avalonia.log");

Debugging Specific Scenarios

Data Binding Issues

Enable binding trace output:
AppBuilder.Configure<App>()
    .UsePlatformDetect()
    .LogToTrace(LogEventLevel.Debug, LogArea.Binding)  // Enable binding logs
    .WithDeveloperTools();
Binding errors will appear in the output window:
Binding Error: Could not resolve property 'UserName' on 'MyApp.ViewModels.MainViewModel'

Layout and Rendering

Enable layout and rendering diagnostics:
AppBuilder.Configure<App>()
    .UsePlatformDetect()
    .LogToTrace(LogEventLevel.Debug, LogArea.Layout, LogArea.Visual)
    .WithDeveloperTools();

Memory Leaks

Detect memory leaks using diagnostic overlays:
using Avalonia.Diagnostics;

Renderer.DrawDirtyRects = true;  // Show dirty rectangles
Renderer.DrawFps = true;          // Show FPS counter

Debugger Attachment

Wait for Debugger

Pause application startup to attach a debugger:
[STAThread]
static int Main(string[] args)
{
    if (args.Contains("--wait-for-attach"))
    {
        Console.WriteLine("Attach debugger and use 'Set next statement'");
        while (true)
        {
            Thread.Sleep(100);
            if (Debugger.IsAttached)
                break;
        }
    }

    return BuildAvaloniaApp()
        .StartWithClassicDesktopLifetime(args);
}
Run with the flag:
dotnet run --wait-for-attach

Conditional Breakpoints

Use conditional breakpoints for targeted debugging:
if (Debugger.IsAttached)
{
    // Conditional debugging code
    Debugger.Break();
}

Designer Support and Previewing

Design-Time Properties

Set design-time data for XAML previewing:
<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:vm="using:MyApp.ViewModels"
        d:DesignWidth="800"
        d:DesignHeight="450">
    <Design.DataContext>
        <vm:MainViewModel />
    </Design.DataContext>
    
    <!-- Your UI here -->
</Window>

Remote Designer

Avalonia’s designer support uses a remote previewer architecture:
  • PreviewerWindowImpl: Provides the window implementation for the previewer
  • RemoteDesignerEntryPoint: Entry point for remote designer instances
  • FileWatcherTransport: Monitors file changes for live preview updates
The designer loads your XAML with:
public static Window LoadDesignerWindow(string xaml, string assemblyPath, 
    string xamlFileProjectPath, double renderScaling)
{
    // Load XAML in design mode
    using (PlatformManager.DesignerMode())
    {
        var loader = AvaloniaLocator.Current
            .GetRequiredService<AvaloniaXamlLoader.IRuntimeXamlLoader>();
        
        var loaded = loader.Load(new RuntimeXamlLoaderDocument(baseUri, stream), 
            new RuntimeXamlLoaderConfiguration
            {
                LocalAssembly = localAsm,
                DesignMode = true,
                UseCompiledBindingsByDefault = true
            });
        
        // Create preview window
        var control = Design.CreatePreviewWithControl(loaded);
        var window = control as Window ?? new Window { Content = control };
        
        return window;
    }
}

Platform-Specific Debugging

Windows

DXGI Debugging

Enable Direct3D debugging for graphics issues:
AppBuilder.Configure<App>()
    .UsePlatformDetect()
    .With(new Win32PlatformOptions
    {
        CompositionMode = new[] 
        { 
            Win32CompositionMode.LowLatencyDxgiSwapChain 
        }
    });

Linux

X11 Debugging

Enable X11-specific debugging:
AppBuilder.Configure<App>()
    .With(new X11PlatformOptions
    {
        EnableMultiTouch = true,
        UseDBusMenu = true,
        EnableIme = true,
    })
    .LogToTrace(LogEventLevel.Debug);

Framebuffer Debugging

For embedded Linux systems:
dotnet run --fbdev --scaling 1.0

DRM Debugging

Direct Rendering Manager debugging:
dotnet run --drm --card /dev/dri/card0 --scaling 2.0

macOS

Metal API Debugging

Enable Metal framework debugging through Xcode.

WebAssembly

Browser Debugging

Enable debugging in browser:
<PropertyGroup>
  <DebuggerSupport>true</DebuggerSupport>
  <WasmDebugLevel>5</WasmDebugLevel>
</PropertyGroup>
Open browser DevTools (F12) and debug your C# code with source maps.

Headless Testing

Run automated UI tests without a display:
AppBuilder.Configure<App>()
    .UseHeadless(new AvaloniaHeadlessPlatformOptions
    {
        UseHeadlessDrawing = true
    })
    .StartWithClassicDesktopLifetime(args);

VNC Preview

View headless applications through VNC:
dotnet run --vnc
Connect to localhost:5901 with a VNC client.

Performance Profiling

Rendering Overlays

Enable visual debugging overlays:
using Avalonia.Rendering;

RendererDebugOverlays = RendererDebugOverlays.Fps | 
                        RendererDebugOverlays.DirtyRects | 
                        RendererDebugOverlays.LayoutTimeGraph;

Composition Debugging

Debug the composition pipeline:
AppBuilder.Configure<App>()
    .With(new CompositionOptions
    {
        UseRegionDirtyRectClipping = true
    });

Vulkan Debugging

Enable Vulkan validation layers:
AppBuilder.Configure<App>()
    .With(new VulkanOptions
    {
        VulkanInstanceCreationOptions = new()
        {
            UseDebug = true
        }
    });

Common Issues and Solutions

Ensure you have:
  • Latest Avalonia extension installed
  • XAML file saved
  • Designer infrastructure initialized
Try rebuilding the project or restarting the designer.
Check:
  1. Property implements INotifyPropertyChanged
  2. Property name matches exactly (case-sensitive)
  3. DataContext is set correctly
  4. Enable binding trace logs:
.LogToTrace(LogEventLevel.Debug, LogArea.Binding)
Likely causes:
  • Long-running operation on UI thread
  • Deadlock in async code
  • Infinite layout loop
Solution: Use DevTools to inspect the visual tree and check which element is causing issues.
Use profiling tools:
  • Visual Studio Diagnostic Tools
  • dotMemory (JetBrains)
  • PerfView (Windows)
Check for:
  • Event handler leaks
  • Unclosed streams
  • Large image caching

Testing and Integration

For comprehensive testing approaches, see:
  • Unit Tests: Located in tests/ directory, categorized by assembly
  • Integration Tests: Located in tests/Avalonia.IntegrationTests.Appium/ using Appium
  • Render Tests: Located in tests/Avalonia.RenderTests/ for visual testing

Additional Resources

DevTools Documentation

Complete DevTools guide and features

Testing Guide

Unit testing and integration testing

Best Practices

Development best practices

Contributing

Contributing guidelines including testing

Next Steps

Now that you understand debugging:
  1. Enable DevTools in your applications
  2. Configure appropriate logging levels
  3. Set up your IDE for optimal debugging
  4. Learn platform-specific debugging techniques
  5. Implement comprehensive testing strategies

Build docs developers (and LLMs) love