Avalonia.Controls.Documents 12.2.1

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Avalonia.Controls.Documents --version 12.2.1
                    
NuGet\Install-Package Avalonia.Controls.Documents -Version 12.2.1
                    
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="Avalonia.Controls.Documents" Version="12.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Avalonia.Controls.Documents" Version="12.2.1" />
                    
Directory.Packages.props
<PackageReference Include="Avalonia.Controls.Documents" />
                    
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 Avalonia.Controls.Documents --version 12.2.1
                    
#r "nuget: Avalonia.Controls.Documents, 12.2.1"
                    
#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 Avalonia.Controls.Documents@12.2.1
                    
#: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=Avalonia.Controls.Documents&version=12.2.1
                    
Install as a Cake Addin
#tool nuget:?package=Avalonia.Controls.Documents&version=12.2.1
                    
Install as a Cake Tool

Avalonia.Controls.Documents

Core document model library for Avalonia rich text controls. Provides rope-based text storage, a hierarchical document tree, text pointers, undo/redo, and snapshotting.

Features

  • Rope-based text storage (RopeTextStore) with O(log n) insert and delete
  • Document tree model (TextDocument, TextDocumentNode) for structural editing
  • Text pointer API (TextPointer, TextRange) with generation-based invalidation
  • Undo/Redo (UndoManager) with structural snapshot support
  • FlowDocument model with blocks (paragraphs, lists, tables, sections) and inlines
  • Document snapshots for thread-safe background serialization

Quick Start

var document = new FlowDocument();
var paragraph = new Paragraph();
paragraph.Inlines.Add(new Run("Hello, world!"));
document.Blocks.Add(paragraph);

Documentation

See the documentation for more details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (6)

Showing the top 5 NuGet packages that depend on Avalonia.Controls.Documents:

Package Downloads
Avalonia.Controls.Markdown

Markdown rendering control for Avalonia applications

Avalonia.Controls.Documents.Serialization.Html

HTML serializer for Avalonia.Controls.Documents

Avalonia.Controls.Documents.Serialization.Rtf

RTF serializer for Avalonia.Controls.Documents with high-fidelity import and export support

Avalonia.Controls.RichTextEditor

Interactive rich text editor control for Avalonia with selection, formatting, and undo/redo support

Avalonia.Controls.Documents.Serialization.Docx

DOCX serializer for Avalonia.Controls.Documents based on Open XML

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
12.2.2 44 7/31/2026
12.2.1 184 7/29/2026
12.2.0 4,148 7/23/2026
12.1.5 8,997 6/29/2026
12.1.4 2,836 6/22/2026
12.1.3 746 6/9/2026
12.1.2 783 6/2/2026
12.1.1 1,181 5/14/2026
12.1.0 734 5/12/2026

## 12.2.1

### Features
- Cross-document element moves: adding a block or inline that is attached to another document now moves it — the element detaches from its old tree preserving its content (each run carries a zero-copy snapshot of its text) and re-attaches with content, structure, formatting and identity intact, recording an undo unit in each document's own stack. Removing an element from a collection is content-preserving for the element in general: the document loses the text, but the detached element keeps it and can be re-added to any document later. Previously a cross-document add silently emptied the source document (or corrupted both documents when neither was materialized yet), and a removed block lost its text on detach.
- A public copy surface for whole documents: `FlowDocument.Clone()` produces a deep, independent copy (content, structure, formatting and page settings; the source is untouched), `FlowDocument.FromSnapshot(DocumentSnapshot)` and `TextDocument.FromSnapshot(...)` are now public so a snapshot can be materialized without a stream round-trip, `TextDocument.Clone()` mirrors the convenience at the model layer, and the public `TextDocument.CreateRangeSnapshot(TextPointer, TextPointer)` captures a sub-range without going through a `TextRange`.
- `FlowDocumentScrollViewer.IsSelectionEnabled` (default `true`) and `FlowDocumentScrollViewer.IsCaretVisible` (default `false`). Turning selection off makes the viewer a pure display control: the inner view stops being focusable — a viewer inside an items-control template no longer steals focus from its list — and the selection, copy and context-menu interactions detach. The blinking caret is now opt-in, matching the WPF viewer, which shows no insertion point in a read-only control.

### Fixes
- Replacing a range's content with a snapshot (`TextRange.InsertSnapshot`, the route pastes and "load into this document" take) no longer loses content. The range's content was removed with a plain text delete, which left every emptied block in the tree and left the range's own start pointer resolved to a node that had gone; the snapshot was then grafted at that dead pointer. Over a range covering a whole document, both the old and the new content disappeared silently; over a smaller multi-block range, the emptied blocks stayed behind as blank paragraphs. The delete now uses replace semantics — blocks the range covers whole are detached and the surviving fragments fuse, the same delete typing over a selection performs — and the snapshot is grafted at the pointer that delete returns.
- Realizing an element no longer reports the document as changed. Building an element on first access raises an Avalonia property change for every inherited value it picks up from the document or host (font, foreground, …); inside an open change scope those marked the scope dirty, so a scope that only realized elements — scrolling a virtualized document into view, reading a lazily loaded block — raised `Changed` as if the document had been edited. Realization and a host releasing the document are now treated the same way: rendering is notified, nothing is recorded, and the document is not marked changed.
- Adding a not-yet-materialized element to a second document no longer leaves it registered in both documents' pending lists — the state that later corrupted both documents when each materialized its own tree around the shared instance. A pending element tracks the collection holding it and is extracted from there before the new collection adopts it.
- A `FlowDocumentScrollViewer` recycled by a virtualizing panel keeps a working selection. Detaching from the visual tree unsubscribed the selection and nothing re-subscribed on re-attach, so `SelectionChanged` stopped firing, `CanCopy` went stale, and the highlight no longer updated after the item scrolled back into view.
- Several views over one `FlowDocument` no longer fight over the shared model. Each view wrote its viewport size into `TextDocument.PageWidth`/`PageHeight` on every layout pass, so the last view to measure won; the write-back is removed and the model's page size carries only what the document itself declares. Serializing an auto-width document (percent-width table columns) is deterministic now — the writers use their own defaults instead of whichever viewport measured last.
- A shared document's logical parent is claimed by exactly one host, with symmetric teardown. Both hosts used to add the document to their logical children while `Parent` pointed at only one of them; the first host to bind now claims the slot (styles and resources resolve against it), later hosts attach without claiming, and a non-owning host letting go of a shared document no longer clears element references another host is still using.
- Showing a document with embedded controls (`BlockUIContainer.Child`, `RichInlineUIContainer.Child`) in a second view renders that container empty there and logs a warning instead of throwing mid-layout — a control has a single visual parent, so it can render in only one view of a shared document at a time.

### Performance
- Virtualized scrolling is block-anchored. The scroll position is an anchor (block plus offset within it) and the realized band is laid out outward from it with measured heights, so per-block layout state is no longer retained for off-screen blocks: memory stays proportional to the viewport instead of the number of blocks visited, and an edit above the viewport no longer shifts the content in view. The scrollbar projects the anchor into an estimated address space — exact whenever the whole document is realized, so small documents keep exact extents and thumb positions, refining as blocks are visited otherwise, with the measured tail keeping the true end of uneven documents reachable. A 100,000-block document lays out its first frame in well under 100 ms, with ~3 ms scrollbar jumps and sub-millisecond wheel steps.
- Attaching a programmatically built document is linear instead of quadratic. Materializing N pending blocks invalidated every derived block position on each attach (forcing a full sibling rescan per block) and scanned the logical children per element, making `InitializeTextDocument` O(N^2) — roughly 3 s for 16,000 blocks and over three minutes for 100,000. Block positions now validate against a per-parent prefix watermark that appends extend in O(1), and the membership check uses a set: 100,000 pending blocks attach in about 0.6 s.