MarkdownWPF 1.1.2
dotnet add package MarkdownWPF --version 1.1.2
NuGet\Install-Package MarkdownWPF -Version 1.1.2
<PackageReference Include="MarkdownWPF" Version="1.1.2" />
<PackageVersion Include="MarkdownWPF" Version="1.1.2" />
<PackageReference Include="MarkdownWPF" />
paket add MarkdownWPF --version 1.1.2
#r "nuget: MarkdownWPF, 1.1.2"
#:package MarkdownWPF@1.1.2
#addin nuget:?package=MarkdownWPF&version=1.1.2
#tool nuget:?package=MarkdownWPF&version=1.1.2
MarkdownWPF
A high-performance, UI-virtualized Markdown renderer for WPF built on Markdig.
Instead of rendering into a heavy FlowDocument, MarkdownWPF generates lightweight WPF elements (TextBlock, Border, Grid, etc.) and hosts them in an ItemsControl with a VirtualizingStackPanel (Recycling mode). Only visible blocks are realized in the visual tree, keeping scrolling smooth and memory usage low even for very large documents.
Features
- True UI virtualization —
VirtualizingStackPanel+ Recycling mode - Multi-target —
net8.0-windowsandnet472 - Markdig pipeline — CommonMark + GFM extensions via
.UseAdvancedExtensions() - XAML styling — Base + override pattern, Static and Dynamic resource resolution
- HTML-in-markdown — Optional extension for
<table>,<ul>/<ol>,<img>,<a>, inline formatting - GFM task lists — Rendered as interactive
CheckBoxelements - Typography replacements — Pandoc symbols
(c),(r),(tm),+-, ellipsis, en/em dashes, punctuation normalization, comma collapse - Subscript / Superscript — H~2~O and E=mc^2^ with
BaselineAlignmentand reducedFontSize - Image caching — Static
ConcurrentDictionaryavoids redundant network/disk loads on re-render - Nested scrolling —
IsScrollViewerEnabledproperty for embedding in externalScrollViewer - Error diagnostics —
ResourceLoadFailedevent for failed image loads and link navigation - Image memory management — Configurable
DecodePixelWidthprevents huge RAM spikes - Last-child margin suppression — Attached property + XAML triggers avoid excessive gaps inside lists/quotes/tables
Installation
dotnet add package MarkdownWPF
For HTML-in-markdown support, also add:
dotnet add package MarkdownWPF.Html
Quick start
1. Merge the default theme
Add the built-in resource dictionary to your App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MarkdownWPF;component/Themes/MarkdownDefaultTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
2. Add the control
<Window xmlns:md="clr-namespace:MarkdownWPF;assembly=MarkdownWPF">
<md:MarkdownViewer Markdown="{Binding MarkdownText}" />
</Window>
That's it. The MarkdownViewer uses the default Markdig pipeline (.UseAdvancedExtensions()) and renders your Markdown into virtualized blocks.
3. (Optional) Enable HTML rendering
If you installed MarkdownWPF.Html, register the HTML extension in your pipeline:
using Markdig;
using MarkdownWPF.Html;
var pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.UseWpfHtml() // registers HTML tag renderers
.Build();
Then pass the pipeline to the viewer:
<md:MarkdownViewer
Markdown="{Binding MarkdownText}"
Pipeline="{Binding Pipeline}" />
Properties
Markdown (string)
The raw Markdown text to render. Changes are applied automatically.
Pipeline (MarkdownPipeline)
The Markdig pipeline to use. Defaults to .UseAdvancedExtensions() if not set.
StyleResourceMode (Static | Dynamic)
Controls how WPF styles are resolved:
| Mode | Behavior |
|---|---|
Static |
Styles are looked up once via TryFindResource and cached. Best for performance when styles don't change at runtime. (Default) |
Dynamic |
Uses SetResourceReference so style changes are picked up live. Useful for theme switching, but has a slight overhead. |
<md:MarkdownViewer StyleResourceMode="Dynamic" />
IsScrollViewerEnabled (bool, default true)
When true, the MarkdownViewer includes a built-in ScrollViewer. Set to false when embedding inside an external ScrollViewer to avoid nested scroll conflicts:
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel>
<TextBlock Text="App header" FontSize="24" />
<md:MarkdownViewer
Markdown="{Binding MarkdownText}"
IsScrollViewerEnabled="False" />
</StackPanel>
</ScrollViewer>
ImageMaxDecodeWidth (int, default 0)
Limits the decode size of images. When set to 0, the viewer automatically uses the screen or window width. This prevents loading a 4000 px photo at full resolution when it will be displayed at 800 px.
Virtualization & performance
The MarkdownViewer extends ItemsControl and uses:
VirtualizingStackPanelas theItemsPanelVirtualizationMode.Recycling— reuses container elementsScrollUnit.Pixel— smooth, per-pixel scrolling
This means:
- Only visible items are created and measured. Off-screen items are recycled.
- Scrolling is smooth even with hundreds of blocks.
- Memory stays low — large documents don't keep thousands of UIElements alive.
Customizing styles
All visuals are driven by standard WPF Style resources. The library uses a safe Base + override pattern:
| Base style (always available) | Working style (override this) | Target type |
|---|---|---|
MarkdownParagraphStyleBase |
MarkdownParagraphStyle |
TextBlock |
MarkdownHeading1StyleBase |
MarkdownHeading1Style |
TextBlock |
MarkdownHeading2StyleBase |
MarkdownHeading2Style |
TextBlock |
MarkdownHeading3StyleBase |
MarkdownHeading3Style |
TextBlock |
MarkdownHeading4StyleBase |
MarkdownHeading4Style |
TextBlock |
MarkdownHeading5StyleBase |
MarkdownHeading5Style |
TextBlock |
MarkdownHeading6StyleBase |
MarkdownHeading6Style |
TextBlock |
MarkdownCodeBlockBorderStyleBase |
MarkdownCodeBlockBorderStyle |
Border |
MarkdownCodeBlockStyleBase |
MarkdownCodeBlockStyle |
TextBlock |
MarkdownThematicBreakStyleBase |
MarkdownThematicBreakStyle |
Border |
MarkdownListStyleBase |
MarkdownListStyle |
StackPanel |
MarkdownListItemStyleBase |
MarkdownListItemStyle |
Grid |
MarkdownListItemMarkerStyleBase |
MarkdownListItemMarkerStyle |
TextBlock |
MarkdownTableStyleBase |
MarkdownTableStyle |
Grid |
MarkdownTableCellStyleBase |
MarkdownTableCellStyle |
Border |
MarkdownTableHeaderCellStyleBase |
MarkdownTableHeaderCellStyle |
Border |
MarkdownBlockquoteStyleBase |
MarkdownBlockQuoteStyle |
Border |
| (none) | MarkdownLinkStyle |
Hyperlink |
| (none) | MarkdownCodeInlineStyle |
Run |
| (none) | MarkdownStrongStyle |
Span |
| (none) | MarkdownEmphasisStyle |
Span |
| (none) | MarkdownStrikethroughStyle |
Span |
| (none) | MarkdownMarkStyle |
Span |
| (none) | MarkdownSubscriptStyle |
Span |
| (none) | MarkdownSuperscriptStyle |
Span |
If a working style is not found in the resource tree, the renderer automatically falls back to the matching Base style — so partial overrides work without errors.
Example: Make H1 headings red
<Window.Resources>
<Style x:Key="MarkdownHeading1Style"
TargetType="TextBlock"
BasedOn="{StaticResource MarkdownHeading1StyleBase}">
<Setter Property="Foreground" Value="Red" />
</Style>
</Window.Resources>
Heading levels 2–6 continue to use their default styles — no extra work needed.
Example: Override link color
<Style x:Key="MarkdownLinkStyle" TargetType="Hyperlink">
<Setter Property="Foreground" Value="Green" />
</Style>
Image caching
Images are cached in a static ConcurrentDictionary<string, BitmapImage> by URL. When the Markdown content changes and trigger a full re-render (e.g. while typing in an editor), previously loaded images are served from cache — no redundant HTTP requests or disk reads.
Use ImageCache.Clear() to flush the cache if needed.
HTML extension reference
When using MarkdownWPF.Html with .UseWpfHtml(), the following HTML tags are supported inside Markdown:
| Tag | Rendered as |
|---|---|
<table>, <tr>, <td>, <th> |
Grid + Border cells |
<ul>, <ol>, <li> |
StackPanel + Grid with markers |
<img> |
Image (cached) |
<a> |
Hyperlink |
<b>, <strong> |
Bold |
<i>, <em> |
Italic |
<u>, <ins> |
Underline |
<s>, <strike>, <del> |
Strikethrough |
<code> |
Inline code span |
<br> |
Line break |
Notes / limitations
- SVG images: WPF does not render SVG out of the box. If your Markdown contains SVG badges, you will need an SVG rendering library or a fallback strategy.
BitmapCacheOption.OnLoad: Network images are loaded synchronously during rendering. For very slow servers this may briefly block the UI thread.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-windows7.0 is compatible. net9.0-windows was computed. net10.0-windows was computed. |
| .NET Framework | net472 is compatible. net48 was computed. net481 was computed. |
NuGet packages (1)
Showing the top 1 NuGet packages that depend on MarkdownWPF:
| Package | Downloads |
|---|---|
|
MarkdownWPF.Html
HTML-in-markdown rendering extension for MarkdownWPF. Adds support for HTML tags <table>, <ul>/<ol>, <img>, <a>, and inline formatting (<b>, <i>, <u>, <s>, <code>) inside Markdown documents rendered by MarkdownWPF. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.2 | 52 | 5/31/2026 |
| 1.1.1 | 55 | 5/31/2026 |
| 1.1.0 | 60 | 5/31/2026 |
| 1.0.0 | 59 | 4/21/2026 |
| 1.0.0-preview3 | 63 | 3/10/2026 |
| 1.0.0-preview2 | 58 | 3/10/2026 |
| 1.0.0-preview1 | 58 | 3/9/2026 |
- Full Markdown block rendering: headings, paragraphs, code blocks, blockquotes, thematic breaks, lists (ordered/unordered), tables
- Inline formatting: bold, italic, strikethrough, mark/highlight, code spans, hyperlinks, autolinks, images
- Subscript (~1) and superscript (^1) rendering with BaselineAlignment
- Typography replacements: Pandoc symbols ((c), (r), (tm), +-), ellipsis normalization, en/em dashes, punctuation normalization, comma collapse
- GFM task list support with CheckBox rendering
- HTML-in-markdown extension: tables, lists, images, links, inline formatting (<b>, <i>, <u>, <s>, <code>)
- VirtualizingStackPanel with recycling mode for smooth scrolling on large documents
- Nested scrolling fix: code blocks no longer swallow mouse wheel events; Shift+MouseWheel passes through for horizontal scroll
- Style system with base+override pattern, Static and Dynamic resource resolution
- Automatic fallback to Base styles when working style is missing
- Image caching to avoid redundant network/disk loads on re-render
- Nested scrolling support (IsScrollViewerEnabled property)
- Error diagnostics: ResourceLoadFailed event for image and navigation failures
- Multi-target: net8.0-windows, net472