PathIcon with Shared StreamGeometryPath and Geometry Composition for Advanced CasesDrawingImage plus ImageImage and BitmapTextBlockUse this reference when you need Fluent-aligned iconography in Avalonia and want a precise answer to three questions:
11.3.12.Primary APIs and surfaces:
PathIconIconElementPathGeometry, StreamGeometry, PathGeometry, GeometryGroup, CombinedGeometryDrawingImage, GeometryDrawingImage, Bitmap, CroppedBitmap, IImageAssetLoaderMenuItem.IconNativeMenuItem.IconWindowIconTrayIcon.IconMacOSProperties.IsTemplateIconTextBlock, Run, FontFamilyThis file complements, not replaces:
02-fluent-typography-layout-shape-and-iconography.md35-path-icons-and-vector-geometry-assets.md55-tray-icons-and-system-tray-integration.md48-toplevel-window-and-runtime-services.mdFor Fluent-style UI, icon quality is mostly a systems problem, not an asset-download problem.
Follow these rules first:
Foreground/theme resources drive their tone,16, 20, or 24,Fluent-specific guidance:
Best-fit public sets for Avalonia apps:
| Set | Best use | Why it fits or does not fit Fluent |
|---|---|---|
| Fluent System Icons | primary choice for Fluent apps | closest visual and metaphor fit to Microsoft Fluent, with regular and filled variants |
| Material Symbols | large coverage, cross-platform app suites | broad set and flexible delivery, but visually reads more Google than Microsoft |
| Lucide | neutral productivity tools | clean outline system, easy to convert to paths, but no Fluent filled/regular pairing model |
| Tabler Icons | dashboards and admin tools | broad OSS catalog with friendly stroke language; visually softer than Fluent |
| Heroicons | simple product and marketing-adjacent surfaces | strong set for clean outline/solid pairs, but stylistically web-oriented |
| Iconoir | broader expressive set | useful when breadth matters, but visual voice is less Fluent-native |
Practical selection rule:
Before adoption, verify:
Avalonia core gives you several valid icon paths, and each solves a different problem.
PathIcon
Geometry and inherits Foreground.Path
DrawingImage used through Image
IImage instead of a control, or when you want a reusable vector-backed image source.Image with Bitmap
TextBlock or Run with an icon font
11.3.12 does not provide a dedicated FontIcon or SymbolIcon; text rendering is the built-in path.WindowIcon for Window.Icon and TrayIcon.Icon.NativeMenuItem.Icon for native menu exports, where the property is Bitmap.For most Fluent apps:
16, 20, and 24.StreamGeometry resources.PathIcon and shared size/foreground styles.Image/Bitmap only for multicolor or brand-sensitive assets.WindowIcon or NativeMenuItem.Icon for OS-level surfaces that do not consume PathIcon.PathIcon with Shared StreamGeometryThis is the default Fluent path for command bars, nav rows, list actions, settings pages, and empty-state supplements.
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<StreamGeometry x:Key="Icon.MailRegular">M3 5H21V19H3Z M3 6.5L12 13L21 6.5</StreamGeometry>
<StreamGeometry x:Key="Icon.MailFilled">M3 5H21V19H3Z</StreamGeometry>
</Application.Resources>
<Application.Styles>
<Style Selector="PathIcon.fluent-command">
<Setter Property="Width" Value="16" />
<Setter Property="Height" Value="16" />
<Setter Property="Foreground" Value="{DynamicResource TextControlForeground}" />
</Style>
</Application.Styles>
</Application>
<Button xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Horizontal" Spacing="8">
<PathIcon Classes="fluent-command"
Data="{StaticResource Icon.MailRegular}" />
<TextBlock VerticalAlignment="Center"
Text="Inbox" />
</StackPanel>
</Button>
Selected-state swap pattern:
<StackPanel xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Orientation="Horizontal"
Spacing="8">
<PathIcon Classes="fluent-command"
Data="{Binding CurrentMailIcon}" />
<TextBlock Text="Inbox" />
</StackPanel>
Use PathIcon when:
Path and Geometry Composition for Advanced CasesUse Path instead of PathIcon when the icon itself needs more control than a semantic icon element.
Examples:
<Viewbox xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="20"
Height="20">
<Canvas Width="20" Height="20">
<Path Data="{StaticResource Icon.BellRegular}"
Fill="{DynamicResource TextControlForeground}" />
<Path Data="M14 2A4 4 0 1 1 14 10A4 4 0 1 1 14 2Z"
Fill="#D13438" />
</Canvas>
</Viewbox>
Geometry composition in code:
using Avalonia;
using Avalonia.Media;
Geometry MakeBadgeIcon()
{
var bell = StreamGeometry.Parse("M10 2C6.7 2 4 4.7 4 8V12L2.5 14V15H17.5V14L16 12V8C16 4.7 13.3 2 10 2Z");
var badge = new EllipseGeometry(new Rect(12, 1, 6, 6));
return new GeometryGroup
{
Children =
{
bell,
badge
}
};
}
Use this path only when you genuinely need icon-level drawing control. For ordinary command symbols, PathIcon is simpler and more Fluent-friendly.
DrawingImage plus ImageDrawingImage is useful when the consuming surface wants an IImage or when you want a reusable vector-backed image source.
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<StreamGeometry x:Key="Icon.Search">M11 2A9 9 0 1 1 4.6 17.3L1 20.9L2.1 22L5.7 18.4A9 9 0 0 1 11 2Z</StreamGeometry>
<DrawingImage x:Key="ImageIcon.Search">
<DrawingImage.Drawing>
<GeometryDrawing Brush="{DynamicResource TextControlForeground}"
Geometry="{StaticResource Icon.Search}" />
</DrawingImage.Drawing>
</DrawingImage>
</Application.Resources>
</Application>
<Image xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="16"
Height="16"
Source="{StaticResource ImageIcon.Search}" />
Use DrawingImage when:
IImage,Image.Source,Image and BitmapUse raster icons for:
Simple XAML pattern:
<Image xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="20"
Height="20"
Stretch="Uniform"
Source="avares://MyApp/Assets/Icons/brand-mark.png" />
Code-loading pattern:
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using var stream = AssetLoader.Open(new Uri("avares://MyApp/Assets/Icons/brand-mark.png"));
var iconBitmap = new Bitmap(stream);
var image = new Image
{
Width = 20,
Height = 20,
Source = iconBitmap
};
Sprite-sheet crop pattern:
using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using var spriteStream = AssetLoader.Open(new Uri("avares://MyApp/Assets/Icons/toolbar-strip.png"));
var spriteSheet = new Bitmap(spriteStream);
var shareBitmap = new CroppedBitmap(spriteSheet, new PixelRect(32, 0, 16, 16));
var shareImage = new Image
{
Width = 16,
Height = 16,
Source = shareBitmap
};
Important note:
11.3.12 does not expose a built-in SVG Image type in this repo’s app-facing API map,Geometry resources is usually the cleaner core-Avalonia path.TextBlockSome public icon libraries ship fonts. Avalonia can use them through normal text rendering.
<StackPanel xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Orientation="Horizontal"
Spacing="8">
<TextBlock FontFamily="avares://MyApp/Assets/Fonts#App Icons"
FontSize="16"
Foreground="{DynamicResource TextControlForeground}"
Text="" />
<TextBlock VerticalAlignment="Center"
Text="Search" />
</StackPanel>
Use the resource directory or an embedded font collection URI for FontFamily; do not point FontFamily at a single .ttf file path.
Use icon fonts when:
Do not assume icon fonts are always the best answer:
For Fluent desktop UI, icon fonts are usually a secondary option behind PathIcon.
Regular Avalonia menu items can host a control as Icon, so PathIcon works well there:
<MenuItem xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Header="_Settings">
<MenuItem.Icon>
<PathIcon Width="16"
Height="16"
Foreground="{DynamicResource TextControlForeground}"
Data="{StaticResource Icon.SettingsRegular}" />
</MenuItem.Icon>
</MenuItem>
Native menus use Bitmap, not PathIcon:
using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using var bitmapStream = AssetLoader.Open(new Uri("avares://MyApp/Assets/Icons/menu-open.png"));
var nativeItem = new NativeMenuItem("Open")
{
Icon = new Bitmap(bitmapStream)
};
Window and tray icons use WindowIcon:
using Avalonia.Controls;
using Avalonia.Platform;
using var iconStream = AssetLoader.Open(new Uri("avares://MyApp/Assets/App/app-icon.ico"));
var appIcon = new WindowIcon(iconStream);
window.Icon = appIcon;
trayIcon.Icon = appIcon;
macOS tray note:
MacOSProperties.IsTemplateIcon="True" on the TrayIcon.| Need | Best Avalonia option |
|---|---|
| single-color Fluent command icon | PathIcon + shared StreamGeometry |
| stroked or layered vector icon | Path + Geometry resources |
reusable vector IImage |
DrawingImage + Image |
| multicolor or brand icon | Image + Bitmap |
| icon font package | TextBlock with custom FontFamily |
| native menu icon | NativeMenuItem.Icon with Bitmap |
| window or tray icon | WindowIcon |
Default recommendation:
PathIcon for in-app Fluent commands,Bitmap or WindowIcon for OS-level surfaces,avares://) for fonts and bitmaps,Geometry or Bitmap.Do:
Icon.SaveRegular, Icon.SaveFilled) instead of numeric,Do not:
Foreground or GeometryDrawing.Brush is bound to the wrong resource.FontFamily URI or family name after # is wrong.PathIcon clips at the edges.
NativeMenuItem.Icon expects a Bitmap, not a PathIcon.MacOSProperties.IsTemplateIcon="True" for menu-bar template behavior.PathIcon: docs.avaloniaui.net/docs/reference/controls/path-iconImage: docs.avaloniaui.net/docs/reference/controls/imageDrawingImage API: api-docs.avaloniaui.net/docs/T_Avalonia_Media_DrawingImageWindowIcon API: api-docs.avaloniaui.net/docs/T_Avalonia_Controls_WindowIconNativeMenuItem.Icon API: api-docs.avaloniaui.net/docs/P_Avalonia_Controls_NativeMenuItem_Icon