TextDocument Class
Definition
Block-level operations for TextDocument (split, merge, etc.).
public class 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:bodystill 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
| Name | Description |
|---|---|
| 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
| Name | Description |
|---|---|
| BeginChange | 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. |
| BeginSelectionContext | 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. |
| Clone | Creates a deep, independent copy of this document. The source is left untouched. |
| CreateRangeSnapshot | Creates a snapshot of the document range between two pointers, preserving block structure by walking the document tree rather than by offset arithmetic. |
| CreateSnapshot | Creates a thread-safe snapshot for background serialization. Must be called from the UI thread. |
| FromSnapshot | No summary available. |
| ResolvePageBandDistance | 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. |
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
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
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
| Name | Description |
|---|---|
| ContentEnd | Gets a pointer to the end of the document — the last caret position in the document's final block, including a trailing empty paragraph. |
| ContentRange | A Avalonia.Controls.Documents.TextModel.TextRange spanning the entire document content. |
| ContentStart | Gets a pointer to the start of the document. |
| DefaultTextFormatting | 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. |
| FootnoteNumberFormat | 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. |
| Footnotes | 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. |
| IsPageHeightFixed | Whether Avalonia.Controls.Documents.TextModel.TextDocument.PageHeight is fixed rather than advisory. |
| IsPageWidthFixed | Whether Avalonia.Controls.Documents.TextModel.TextDocument.PageWidth is fixed rather than advisory. |
| IsUpdating | Returns true if a change block is in progress. |
| Length | Gets the total character length of the document text. |
| PageBandDistance | 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. |
| PageBands | 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. |
| PageHeight | The page height, or to grow with content. |
| PagePadding | The padding inside the page, or for the default. |
| PageSetup | 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. |
| PageWidth | The page width, or to size to the viewport. |
| UndoManager | 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 . |
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
| Name | Description |
|---|---|
| Changed | 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. |
| FootnotesChanged | Raised when the set of notes changes or a note's id or label changes. |
| PageBandsChanged | 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. |
| TextChanged | 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. |
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).