Skip to main content

TextDocument Class

Definition​

Assembly:Avalonia.Controls.Documents
Package:Avalonia.Controls.Documents

Block-level operations for TextDocument (split, merge, etc.).

public class TextDocument

Inheritance: object -> TextDocument

Remarks​

Mirrors the approach used by MarkdownStreamingSession.ApplyDelta: the snapshot's rope tree is spliced into the live document and its top-level Avalonia.Controls.Documents.Serialization.Snapshot.SnapshotNode children are converted into Avalonia.Controls.Documents.TextModel.TextDocumentNode sub-trees with deferred element realization, then attached as siblings of the caret block.

Two structural paths are supported:

  • Root-block boundary (caret at start or end of a root paragraph, empty document, or single empty placeholder paragraph): blocks splice as siblings of the caret block.
  • Mid-paragraph (caret strictly inside a root-level paragraph): the paragraph is split via Avalonia.Controls.Documents.TextModel.TextDocument.SplitBlock(Avalonia.Controls.Documents.TextModel.TextPointer,bool), snapshot blocks splice between the halves, and the first/last grafted paragraphs merge with the surrounding split halves. Top-level Sections that carry no formatting are unwrapped before the graft so RTF/DOCX round-trips that wrap content in \sectd/w:body still merge cleanly.

Other contexts (caret inside a Avalonia.Controls.Documents.ListItem / Avalonia.Controls.Documents.TableCell paragraph, formatted Section interior) fall back to plain-text lowering. Schema-aware structural paste in those contexts is a follow-up.

The insertion anchor is a Avalonia.Controls.Documents.TextModel.TextPointer rather than a raw offset. The pointer carries the tree node it was bound to, so block resolution does not depend on offset arithmetic — it walks up from pointer.Node until it reaches a child of Avalonia.Controls.Documents.TextModel.TextDocument.RootNode.

Constructors​

NameDescription
TextDocument (3 overloads)Initializes an empty document with a root node.

TextDocument overloads​

TextDocument Constructor​

Initializes an empty document with a root node.

public TextDocument()

TextDocument Constructor​

Initializes an empty document whose root has rootKind: Avalonia.Controls.Documents.TextModel.TextDocumentNodeKind.Document, or Avalonia.Controls.Documents.TextModel.TextDocumentNodeKind.PageBand for a page band's content.

public TextDocument(Avalonia.Controls.Documents.TextModel.TextDocumentNodeKind rootKind)
Parameters​

rootKind Avalonia.Controls.Documents.TextModel.TextDocumentNodeKind

TextDocument Constructor​

Initializes a document with the specified initial text content.

public TextDocument(string initialText)
Parameters​

initialText string

The initial text content.

Methods​

NameDescription
BeginChangeOpens a change block that batches document edits into a single undo unit and deferred layout update. Dispose the returned scope to close the block.
BeginSelectionContextOpens a selection-tracking scope that attaches caret/selection metadata to any undo unit produced by a Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange block opened while the scope is active. The pre-edit snapshot is captured when the outermost Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange opens, and the post-edit snapshot is captured when it closes — both from the same live selection reference.
CloneCreates a deep, independent copy of this document. The source is left untouched.
CreateRangeSnapshotCreates a snapshot of the document range between two pointers, preserving block structure by walking the document tree rather than by offset arithmetic.
CreateSnapshotCreates a thread-safe snapshot for background serialization. Must be called from the UI thread.
FromSnapshotNo summary available.
ResolvePageBandDistanceThe distance the pagination engines apply: the document's, clamped to non-negative, and Avalonia.Controls.Documents.PageBandPolicy.DefaultDistance where the document declares nothing usable.

BeginChange Method​

Opens a change block that batches document edits into a single undo unit and deferred layout update. Dispose the returned scope to close the block.

public IDisposable BeginChange()

Returns​

IDisposable

BeginSelectionContext Method​

Opens a selection-tracking scope that attaches caret/selection metadata to any undo unit produced by a Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange block opened while the scope is active. The pre-edit snapshot is captured when the outermost Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange opens, and the post-edit snapshot is captured when it closes — both from the same live selection reference.

public IDisposable BeginSelectionContext(Avalonia.Controls.TextSelection selection)

Parameters​

selection Avalonia.Controls.TextSelection

Returns​

IDisposable

Remarks​

This is an orthogonal, opt-in facility. It does not alter the Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange API surface. Typical usage wraps the change scope:

using (document.BeginSelectionContext(selection))
using (document.BeginChange())
{
// edit...
}

Only one selection context is active at a time; nested calls preserve the outer reference and restore it on dispose. The context must be opened before Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange to participate in the undo unit's pre-edit snapshot.

Clone Method​

Creates a deep, independent copy of this document. The source is left untouched.

public Avalonia.Controls.Documents.TextModel.TextDocument Clone()

Returns​

Avalonia.Controls.Documents.TextModel.TextDocument

CreateRangeSnapshot Method​

Creates a snapshot of the document range between two pointers, preserving block structure by walking the document tree rather than by offset arithmetic.

public Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot CreateRangeSnapshot(Avalonia.Controls.Documents.TextModel.TextPointer start, Avalonia.Controls.Documents.TextModel.TextPointer end)

Parameters​

start Avalonia.Controls.Documents.TextModel.TextPointer

Start of the range.

end Avalonia.Controls.Documents.TextModel.TextPointer

End of the range.

Returns​

Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot

A snapshot containing only the range content.

Remarks​

Block membership is decided structurally: the snapshot contains every top-level block from start's block through end's block, inclusive. Because the boundary blocks are the pointers' resolved nodes — carrying node identity and gravity — rather than a half-open offset interval, a zero-length block the end pointer lands in (e.g. a trailing empty paragraph reached by Select-All) is captured naturally instead of being skipped. Offsets are used only where they are the natural primitive: slicing the rope text and trimming partially-selected boundary blocks.

CreateSnapshot Method​

Creates a thread-safe snapshot for background serialization. Must be called from the UI thread.

public Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot CreateSnapshot()

Returns​

Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot

An immutable snapshot that can be safely read from any thread.

Remarks​

The snapshot captures the document's current state including:

  • Text content (O(1) - references immutable rope nodes)
  • Tree structure (O(n) - copies node tree)
  • Formatting (O(n) - captures as value types)

Typical use for background serialization:

var snapshot = document.CreateSnapshot();
await Task.Run(() => serializer.Serialize(snapshot, stream));

FromSnapshot Method​

public Avalonia.Controls.Documents.TextModel.TextDocument FromSnapshot(Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot snapshot, Action<Avalonia.Controls.Documents.RichTextElement, Avalonia.Controls.Documents.Serialization.Snapshot.SnapshotNode> formatCallback)

Parameters​

snapshot Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot

formatCallback Action<Avalonia.Controls.Documents.RichTextElement, Avalonia.Controls.Documents.Serialization.Snapshot.SnapshotNode>

Returns​

Avalonia.Controls.Documents.TextModel.TextDocument

ResolvePageBandDistance Method​

The distance the pagination engines apply: the document's, clamped to non-negative, and Avalonia.Controls.Documents.PageBandPolicy.DefaultDistance where the document declares nothing usable.

public double ResolvePageBandDistance()

Returns​

double

Properties​

NameDescription
ContentEndGets a pointer to the end of the document — the last caret position in the document's final block, including a trailing empty paragraph.
ContentRangeA Avalonia.Controls.Documents.TextModel.TextRange spanning the entire document content.
ContentStartGets a pointer to the start of the document.
DefaultTextFormattingThe document's default text formatting: the font, size, foreground and background every block and inline inherits unless it declares its own. It belongs to the root node, which never realizes an element in a document used model-first, so the model keeps it here and the snapshot carries it on Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot.Root.
FootnoteNumberFormatGets or sets how the document numbers its footnotes: the format of the ordinal each anchor renders and its note shows in its number strip. Nothing is stored in the anchors: setting it is one undo unit and raises Avalonia.Controls.Documents.TextModel.TextDocument.FootnotesChanged, from which the views re-render. A nested document (a page band, a footnote) has no numbering of its own and refuses any value but the default.
FootnotesThe footnotes this document owns, in anchor order: nested documents paired by id with the Avalonia.Controls.Documents.TextModel.TextDocumentNodeKind.FootnoteReference anchors in the body. The text model is complete without an element facade: the notes snapshot and restore with the document.
IsPageHeightFixedWhether Avalonia.Controls.Documents.TextModel.TextDocument.PageHeight is fixed rather than advisory.
IsPageWidthFixedWhether Avalonia.Controls.Documents.TextModel.TextDocument.PageWidth is fixed rather than advisory.
IsUpdatingReturns true if a change block is in progress.
LengthGets the total character length of the document text.
PageBandDistanceGets or sets the distance from the sheet edge to a page band in DIPs: the header's top sits this far below the sheet top, the footer's bottom this far above the sheet bottom. Null (the default) means Avalonia.Controls.Documents.PageBandPolicy.DefaultDistance.
PageBandsThe page bands this document owns: nested documents placed by their role and rule or by a section's references. The text model is complete without an element facade: the bands snapshot and restore with the document, and Avalonia.Controls.Documents.PageBandPolicy resolves a page's band from the nodes.
PageHeightThe page height, or to grow with content.
PagePaddingThe padding inside the page, or for the default.
PageSetupGets or sets the document-wide page setup: padding, page size and whether either dimension is fixed, the page-band distance and the footnote numbering.
PageWidthThe page width, or to size to the viewport.
UndoManagerGets or sets the undo manager associated with this document. The owning Avalonia.Controls.Documents.FlowDocument passes it on to its page bands, so one document family drives one stack. records nothing, as does a manager whose Avalonia.Controls.Documents.Undo.UndoManager.IsEnabled is .

ContentEnd Property​

Gets a pointer to the end of the document — the last caret position in the document's final block, including a trailing empty paragraph.

public Avalonia.Controls.Documents.TextModel.TextPointer ContentEnd { get; set; }

Remarks​

Returns the document's cached instance, not a fresh allocation. See Avalonia.Controls.Documents.TextModel.TextDocument.ContentStart for the cloning requirement.

The pointer is anchored to the final block by node identity rather than a raw (Length, Backward) offset. The two differ only when the document ends in an empty paragraph: that paragraph is zero-length and shares its offset with the end of the preceding block, so a backward-bound offset pointer resolves to the preceding block and leaves the empty paragraph beyond the document end. Anchoring to the last block keeps ContentEnd — and everything derived from it (Avalonia.Controls.Documents.TextModel.TextDocument.ContentRange, Select-All, end-of-document navigation, range snapshots) — spanning the whole structure.

ContentRange Property​

A Avalonia.Controls.Documents.TextModel.TextRange spanning the entire document content.

public Avalonia.Controls.Documents.TextModel.TextRange ContentRange { get; set; }

Remarks​

Each read allocates a new range, so the mutation verbs Avalonia.Controls.Documents.TextModel.TextRange exists for — DeleteText, ReplaceText, InsertSnapshot — re-target only the instance the caller holds. Reading the property twice yields two ranges that compare equal but are not the same object.

ContentStart Property​

Gets a pointer to the start of the document.

public Avalonia.Controls.Documents.TextModel.TextPointer ContentStart { get; set; }

Remarks​

Returns the document's cached instance, not a fresh allocation. Callers that store the result in a mutable container (e.g. Avalonia.Controls.Documents.TextModel.TextRange endpoints, undo records) must call Avalonia.Controls.Documents.TextModel.TextPointer.Clone first; otherwise a later UpdateInPlace/Refresh through that container will shift the document's cached origin pointer and corrupt every future Avalonia.Controls.Documents.TextModel.TextDocument.ContentStart read at the current generation.

DefaultTextFormatting Property​

The document's default text formatting: the font, size, foreground and background every block and inline inherits unless it declares its own. It belongs to the root node, which never realizes an element in a document used model-first, so the model keeps it here and the snapshot carries it on Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot.Root.

public Avalonia.Controls.Documents.TextModel.Formatting.TextElementFormatting DefaultTextFormatting { get; set; }

FootnoteNumberFormat Property​

Gets or sets how the document numbers its footnotes: the format of the ordinal each anchor renders and its note shows in its number strip. Nothing is stored in the anchors: setting it is one undo unit and raises Avalonia.Controls.Documents.TextModel.TextDocument.FootnotesChanged, from which the views re-render. A nested document (a page band, a footnote) has no numbering of its own and refuses any value but the default.

public Avalonia.Controls.Documents.FootnoteNumberFormat FootnoteNumberFormat { get; set; }

Footnotes Property​

The footnotes this document owns, in anchor order: nested documents paired by id with the Avalonia.Controls.Documents.TextModel.TextDocumentNodeKind.FootnoteReference anchors in the body. The text model is complete without an element facade: the notes snapshot and restore with the document.

public Avalonia.Controls.Documents.TextModel.TextFootnoteCollection Footnotes { get; set; }

IsPageHeightFixed Property​

Whether Avalonia.Controls.Documents.TextModel.TextDocument.PageHeight is fixed rather than advisory.

public bool IsPageHeightFixed { get; set; }

Remarks​

A facade over Avalonia.Controls.Documents.TextModel.TextDocument.PageSetup, which is the property that records an undo unit and marks the change scope. Setting one of these five reads the whole setup, replaces one value and writes it back, so setting several in a row records several units; assign a Avalonia.Controls.Documents.TextModel.Formatting.DocumentFormatting once instead.

IsPageWidthFixed Property​

Whether Avalonia.Controls.Documents.TextModel.TextDocument.PageWidth is fixed rather than advisory.

public bool IsPageWidthFixed { get; set; }

Remarks​

A facade over Avalonia.Controls.Documents.TextModel.TextDocument.PageSetup, which is the property that records an undo unit and marks the change scope. Setting one of these five reads the whole setup, replaces one value and writes it back, so setting several in a row records several units; assign a Avalonia.Controls.Documents.TextModel.Formatting.DocumentFormatting once instead.

IsUpdating Property​

Returns true if a change block is in progress.

public bool IsUpdating { get; set; }

Length Property​

Gets the total character length of the document text.

public int Length { get; set; }

PageBandDistance Property​

Gets or sets the distance from the sheet edge to a page band in DIPs: the header's top sits this far below the sheet top, the footer's bottom this far above the sheet bottom. Null (the default) means Avalonia.Controls.Documents.PageBandPolicy.DefaultDistance.

public Nullable<double> PageBandDistance { get; set; }

Remarks​

A band taller than the space this leaves pushes the body down, so the value decides where pages break, and screen, print and PDF all resolve it from here through Avalonia.Controls.Documents.TextModel.TextDocument.ResolvePageBandDistance.

PageBands Property​

The page bands this document owns: nested documents placed by their role and rule or by a section's references. The text model is complete without an element facade: the bands snapshot and restore with the document, and Avalonia.Controls.Documents.PageBandPolicy resolves a page's band from the nodes.

public Avalonia.Controls.Documents.TextModel.TextPageBandCollection PageBands { get; set; }

PageHeight Property​

The page height, or to grow with content.

public Nullable<double> PageHeight { get; set; }

Remarks​

A facade over Avalonia.Controls.Documents.TextModel.TextDocument.PageSetup, which is the property that records an undo unit and marks the change scope. Setting one of these five reads the whole setup, replaces one value and writes it back, so setting several in a row records several units; assign a Avalonia.Controls.Documents.TextModel.Formatting.DocumentFormatting once instead.

PagePadding Property​

The padding inside the page, or for the default.

public Nullable<Avalonia.Thickness> PagePadding { get; set; }

Remarks​

A facade over Avalonia.Controls.Documents.TextModel.TextDocument.PageSetup, which is the property that records an undo unit and marks the change scope. Setting one of these five reads the whole setup, replaces one value and writes it back, so setting several in a row records several units; assign a Avalonia.Controls.Documents.TextModel.Formatting.DocumentFormatting once instead.

PageSetup Property​

Gets or sets the document-wide page setup: padding, page size and whether either dimension is fixed, the page-band distance and the footnote numbering.

public Avalonia.Controls.Documents.TextModel.Formatting.DocumentFormatting PageSetup { get; set; }

Remarks​

This is the same record a Avalonia.Controls.Documents.Serialization.Snapshot.DocumentSnapshot carries, so what reaches a file and what an attached view reads are the same value. Setting it is one undo unit and one change scope, from which the views re-measure; band distance and footnote numbering also raise their own change events so the parts of a view that listen for those alone still see the edit.

Avalonia.Controls.Documents.TextModel.TextDocument.PageBandDistance and Avalonia.Controls.Documents.TextModel.TextDocument.FootnoteNumberFormat write into the same state and are the shorter form when only one value moves.

Exceptions​

PageWidth Property​

The page width, or to size to the viewport.

public Nullable<double> PageWidth { get; set; }

Remarks​

A facade over Avalonia.Controls.Documents.TextModel.TextDocument.PageSetup, which is the property that records an undo unit and marks the change scope. Setting one of these five reads the whole setup, replaces one value and writes it back, so setting several in a row records several units; assign a Avalonia.Controls.Documents.TextModel.Formatting.DocumentFormatting once instead.

UndoManager Property​

Gets or sets the undo manager associated with this document. The owning Avalonia.Controls.Documents.FlowDocument passes it on to its page bands, so one document family drives one stack. records nothing, as does a manager whose Avalonia.Controls.Documents.Undo.UndoManager.IsEnabled is .

public Avalonia.Controls.Documents.Undo.IUndoManager UndoManager { get; set; }

Events​

NameDescription
ChangedRaised when an outermost Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange scope completes after producing at least one observable change. Empty / no-op scopes are suppressed entirely.
FootnotesChangedRaised when the set of notes changes or a note's id or label changes.
PageBandsChangedRaised when the set of bands changes or a band's role or rule changes: the pages a band claims by rule follow from these, so views re-resolve.
TextChangedRaised after each individual edit operation (insert, delete, replace). Carries Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.Offset, Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.OldLength, Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.NewLength, Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.Kind, and Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.InsertedText.

Changed Event​

Raised when an outermost Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange scope completes after producing at least one observable change. Empty / no-op scopes are suppressed entirely.

public event EventHandler<Avalonia.Controls.Documents.TextModel.DocumentChangedEventArgs> Changed

Remarks​

The event payload aggregates every Avalonia.Controls.Documents.TextModel.TextChangeEventArgs that fired in the scope, plus the Avalonia.Controls.Documents.TextModel.ChangeOrigin and the originating Avalonia.Controls.Documents.Undo.IUndoUnit when undo is enabled.

FootnotesChanged Event​

Raised when the set of notes changes or a note's id or label changes.

public event EventHandler FootnotesChanged

PageBandsChanged Event​

Raised when the set of bands changes or a band's role or rule changes: the pages a band claims by rule follow from these, so views re-resolve.

public event EventHandler PageBandsChanged

TextChanged Event​

Raised after each individual edit operation (insert, delete, replace). Carries Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.Offset, Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.OldLength, Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.NewLength, Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.Kind, and Avalonia.Controls.Documents.TextModel.TextChangeEventArgs.InsertedText.

public event EventHandler<Avalonia.Controls.Documents.TextModel.TextChangeEventArgs> TextChanged

Remarks​

Multiple Avalonia.Controls.Documents.TextModel.TextDocument.TextChanged events may fire within a single Avalonia.Controls.Documents.TextModel.TextDocument.BeginChange scope. Use Avalonia.Controls.Documents.TextModel.TextDocument.Changed for the per-commit aggregate (with undo correlation).