Table of Contents

Class DesignDocument

Namespace
Icy.Design
Assembly
IcyUI.Design.dll

One tracked markup file: its text, its syntax tree, and the live objects built from it.

public sealed class DesignDocument
Inheritance
DesignDocument
Inherited Members
Extension Methods

Remarks

The text is the source of truth. Every edit made through Editor changes the text with a minimal TextChangeSet, re-parses it, and mirrors the change onto every live tree built from this file. Saving writes the text as is, so formatting, comments and anything the editor doesn't understand survive.

A document must be used on the thread that owns its pages, like the pages themselves.

Properties

CanSave

Gets a value indicating whether Save() has a file to write.

public bool CanSave { get; }

Property Value

bool

Editor

Gets the editor that changes this document and mirrors every change onto its live pages.

public MarkupEditor Editor { get; }

Property Value

MarkupEditor

IsInSync

Gets a value indicating whether the live pages reflect the current text: the text has no syntax errors, every part of the last ApplyText(string) was mirrored, and the root didn't change in a way that needs a reload.

public bool IsInSync { get; }

Property Value

bool

IsModified

Gets a value indicating whether the text differs from what was last loaded or saved.

public bool IsModified { get; }

Property Value

bool

Remarks

It compares the text itself, not the undo position, so undoing back to the saved text makes it false again even when the undo stack coalesced several edits into one step.

LiveErrors

Gets why the live pages don't reflect the current text: the parts of the last ApplyText(string) that failed to mirror, with the text they concern. Syntax errors are in Diagnostics.

public IReadOnlyList<Diagnostic> LiveErrors { get; }

Property Value

IReadOnlyList<Diagnostic>

NeedsReload

Gets a value indicating whether an edit changed the text in a way the live pages couldn't follow (an edit inside a style, a template or a property element, or a change to the root that needs a new root object). The text is still right; reload the page to see it.

public bool NeedsReload { get; }

Property Value

bool

SaveBlockedReason

Gets why Save() can't write, or null when it can.

public string? SaveBlockedReason { get; }

Property Value

string

Remarks

The reason is either that the page has no SourcePath, or that SourcePathResolver doesn't resolve it to a file (see UseSourceRoot(string)).

Session

Gets the session tracking this document.

public DesignSession Session { get; }

Property Value

DesignSession

SourcePath

Gets the path the document was loaded from, as passed to the loader, or null.

public string? SourcePath { get; }

Property Value

string

Syntax

Gets the current syntax tree.

public DocumentSyntax Syntax { get; }

Property Value

DocumentSyntax

Text

Gets the current markup text.

public string Text { get; }

Property Value

string

Version

Gets the text's version: 0 when loaded, plus one for every change.

public int Version { get; }

Property Value

int

Methods

ApplyText(string)

Replaces the whole text and updates the live pages to match, keeping every element that still corresponds, with its runtime state. This is how saved files and typed text reach a running page.

public EditResult ApplyText(string newText)

Parameters

newText string

The new markup text.

Returns

EditResult

Always a success: the text is stored and recorded as one undo step even when the live pages can't follow all of it. Check IsInSync and LiveErrors for that.

Remarks

  • Malformed text changes nothing live; the pages wait for the next well-formed text.
  • Well-formed text is diffed against the last tree the pages followed. Each part is mirrored on its own: one part that fails (a value that doesn't convert, say) is reported in LiveErrors and doesn't stop the others, and the next ApplyText(string) rebuilds what failed.
  • Identical text changes nothing and records nothing.

Exceptions

ArgumentNullException

newText is null.

ObjectDisposedException

The document's session was disposed.

InvalidOperationException

The calling thread doesn't own the document's pages.

GetNode(NodeId)

Gets the markup element with the given id in the current syntax tree.

public ElementSyntax? GetNode(NodeId id)

Parameters

id NodeId

The element's id.

Returns

ElementSyntax

The element, or null when no element of the current text has that id.

GetNodeId(ElementSyntax)

Gets the id of an element of the current syntax tree.

public NodeId? GetNodeId(ElementSyntax element)

Parameters

element ElementSyntax

An element of Syntax.

Returns

NodeId?

The id, or null when element isn't part of the current tree.

GetObjects(NodeId)

Gets the live objects built from a markup element: one per load of this file still alive.

public IReadOnlyList<object> GetObjects(NodeId id)

Parameters

id NodeId

The element's id.

Returns

IReadOnlyList<object>

The live objects; empty when none are alive or the element is opaque (inside a template, say).

ReloadFromSource()

Reads the file SourcePath resolves to through SourcePathResolver, and applies its text with ApplyText(string).

public bool ReloadFromSource()

Returns

bool

false, changing nothing, when the source path doesn't resolve to a file.

Exceptions

ObjectDisposedException

The document's session was disposed.

IOException

The file couldn't be read.

Save()

Writes the text to the file SourcePath resolves to through SourcePathResolver.

public void Save()

Exceptions

InvalidOperationException

The document has no source path, or it doesn't resolve to a file.

IOException

The file couldn't be written.

SaveAs(string)

Writes the text, exactly as it is, to filePath as UTF-8 without a byte order mark.

public void SaveAs(string filePath)

Parameters

filePath string

The file to write.

Exceptions

ArgumentException

filePath is null or empty.

IOException

The file couldn't be written.

TryGetNodeId(object, out NodeId)

Finds the markup element a live object was built from.

public bool TryGetNodeId(object instance, out NodeId id)

Parameters

instance object

The live object.

id NodeId

The element's id.

Returns

bool

true when instance was built from this document.

Events

Changed

Occurs after the text changed, with the exact changes made.

public event EventHandler<DocumentChangedEventArgs>? Changed

Event Type

EventHandler<DocumentChangedEventArgs>

DiagnosticsChanged

Occurs when the syntax tree's Diagnostics changed.

public event EventHandler? DiagnosticsChanged

Event Type

EventHandler

ModifiedChanged

Occurs when IsModified changed.

public event EventHandler? ModifiedChanged

Event Type

EventHandler

NeedsReloadChanged

Occurs when NeedsReload becomes true.

public event EventHandler? NeedsReloadChanged

Event Type

EventHandler

SubtreeReplaced

Occurs when an edit had to rebuild a live subtree instead of updating it in place.

public event EventHandler<SubtreeReplacedEventArgs>? SubtreeReplaced

Event Type

EventHandler<SubtreeReplacedEventArgs>

SyncStateChanged

Occurs when IsInSync or LiveErrors changed.

public event EventHandler? SyncStateChanged

Event Type

EventHandler