Control: TheTechIdea.Beep.WPF.Controls.BeepImage (derives ContentControl)  ·  Icon catalog: Icons/SvgsUIcons.cs over the embedded SVGs in GFX/Icons/uiicons/.

The four source formats

You point BeepImage (or any icon DP) at a string. The pipeline detects the format from the string content — no flag, no per-format API. Embedded resource first, then .svg extension, else a bitmap.

FormatExampleUse case
Embedded SVG by name fi-tr-floppy-disk The common case. Resolved via Icons/SvgsUIcons.cs against the embedded SVGs in GFX/Icons/uiicons/. Same names as the WinForms library — no path, no extension.
Pack URI pack://application:,,,/MyApp;component/Icons/open.svg Icons shipped inside the consumer app's own assembly.
File path C:/icons/cog.svg, ./logo.png Dev-time quick pointing at a file on disk.
Inline path geometry M12 21.35l-1.45-1.32C5.4 15.36... A raw path-geometry string (starts with M/m/L/…). No file — a pure vector primitive, recolored via Foreground.
Bitmap fallback ./logo.png, photo.jpg Any non-.svg extension is loaded as a BitmapImage.

The detection order (from BeepImage.LoadImageFromPath):

if (IsEmbeddedResource(path)) { LoadImageFromEmbeddedResource(path); return; }
_isSvg = path.EndsWith(".svg", StringComparison.OrdinalIgnoreCase);
if (_isSvg) LoadSvgImage(path);
else        LoadBitmapImage(path);

Setting an icon by name is the whole API — no pipeline to wire on the consumer side:

<beep:BeepImage ImagePath="fi-tr-floppy-disk" Width="20" Height="20"/>

<!-- pack URI -->
<beep:BeepImage ImagePath="pack://application:,,,/MyApp;component/Icons/open.svg"/>

<!-- file path -->
<beep:BeepImage ImagePath="C:/icons/cog.svg"/>

<!-- inline path geometry -->
<beep:BeepImage ImagePath="M12 2 L2 22 L22 22 Z"/>

Empty string = no icon

The default and the "no icon" value is the empty string "". Templates bind an icon slot's visibility through StringToVisibilityConverter, which returns Collapsed for null/empty and Visible for any non-empty string. That is the WPF-idiomatic way to conditionally show a chrome slot — the slot simply collapses when no icon is set, leaving no gap.

<beep:BeepImage Grid.Column="0"
                ImagePath="{TemplateBinding LeadingIcon}"
                Visibility="{Binding LeadingIcon,
                             RelativeSource={RelativeSource TemplatedParent},
                             Converter={StaticResource StringToVisibility}}"/>
Don't special-case "hide the icon" in code. Leave the DP at "" and let the converter collapse the slot. Setting a non-empty name is the only thing that lights it up.

Foreground recolors SVGs

SVG content (embedded, file, pack URI, or inline path geometry) is recolored by the Foreground brush — applied automatically when the image renders. Because that brush comes from the active skin's tokens, icons re-tint when the theme swaps, in step with the surrounding chrome. BeepImage exposes Foreground plus Stroke/Fill/Background brush DPs for finer control, and its own ImagePath, ImageSource, Stretch and IsStillImage properties.

<!-- Icon follows the skin's OnSurface tone via a chrome token -->
<beep:BeepImage ImagePath="fi-tr-search"
                Foreground="{DynamicResource BeepChrome.IconForeground}"
                Width="18" Height="18"/>

Because the recolor is driven by Foreground, a single embedded SVG serves every skin — there is no light/dark variant of an icon asset; the brush changes, not the file.

Any string icon DP uses this pipeline

The icon pipeline is not exclusive to BeepImage. Every control that exposes a string icon DP feeds it through the same resolver — its template hosts a BeepImage in the icon slot and binds the DP to ImagePath. So the same four formats, the same empty-string rule, and the same Foreground recolor apply everywhere.

HostString icon DP(s)
IBeepIconHost (implemented by many inputs/buttons)LeadingIcon, TrailingIcon (+ IconSize)
BeepListItem (the rich list row)LeadingIcon, TrailingIcon, ActionIcon
Buttons / text inputs / search boxesLeadingIcon / TrailingIcon

Set the icon by name — the host does the rest:

<beep:BeepTextBox LeadingIcon="fi-tr-search"/>

<beep:BeepButton Text="Save" LeadingIcon="fi-tr-floppy-disk"/>

<beep:BeepListItem PrimaryText="Documents"
                   LeadingIcon="fi-tr-folder"
                   TrailingIcon="fi-tr-angle-right"/>
Icons sit INSIDE the chrome border. In a control template the leading/trailing icon BeepImage slots are grid columns inside the themed RootBorder (leading | content | trailing), not siblings of it — otherwise they render free-floating with no chrome. See Chrome, Skins & Themes for the token system that paints that border.

Gotchas

  • The icon name must exist. Every embedded-SVG name must resolve to a real file in GFX/Icons/uiicons/. A typo returns silently — the image just doesn't render — and, when the BeepImage is composed inside a control template first instantiated at app start, a missing resource can surface as a runtime XamlParseException on first init. Confirm a name exists before referencing it (e.g. ls GFX/Icons/uiicons/ | grep -i <name>).
  • Some plausible names don't exist. fi-tr-circle-exclamation and fi-tr-circle-info are not in the catalog. Safe alternatives that are: fi-tr-alarm-exclamation, fi-tr-info, fi-tr-warning.
  • Prefer names over paths in shipped UI. Embedded names travel with the library and re-tint with the theme; a file path is a dev-time convenience that won't exist on another machine.