MarkdownWPF.Html 1.1.2

dotnet add package MarkdownWPF.Html --version 1.1.2
                    
NuGet\Install-Package MarkdownWPF.Html -Version 1.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MarkdownWPF.Html" Version="1.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MarkdownWPF.Html" Version="1.1.2" />
                    
Directory.Packages.props
<PackageReference Include="MarkdownWPF.Html" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MarkdownWPF.Html --version 1.1.2
                    
#r "nuget: MarkdownWPF.Html, 1.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MarkdownWPF.Html@1.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MarkdownWPF.Html&version=1.1.2
                    
Install as a Cake Addin
#tool nuget:?package=MarkdownWPF.Html&version=1.1.2
                    
Install as a Cake Tool

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 virtualizationVirtualizingStackPanel + Recycling mode
  • Multi-targetnet8.0-windows and net472
  • 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 CheckBox elements
  • 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 BaselineAlignment and reduced FontSize
  • Image caching — Static ConcurrentDictionary avoids redundant network/disk loads on re-render
  • Nested scrollingIsScrollViewerEnabled property for embedding in external ScrollViewer
  • Error diagnosticsResourceLoadFailed event for failed image loads and link navigation
  • Image memory management — Configurable DecodePixelWidth prevents 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:

  • VirtualizingStackPanel as the ItemsPanel
  • VirtualizationMode.Recycling — reuses container elements
  • ScrollUnit.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.

<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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.2 81 5/31/2026
1.1.1 79 5/31/2026
1.1.0 93 5/31/2026

- HTML tag rendering: tables (<table>, <tr>, <td>, <th>), lists (<ul>, <ol>, <li>), images, links
- Inline formatting: <b>, <strong>, <i>, <em>, <u>, <ins>, <s>, <del>, <code>
- Integration with MarkdownWPF styling system
- Full HTML table layout with dynamic Grid generation
- Ordered list support with custom start attribute