State Query Service

The WPF IStateQueryService interface is the read-only mirror of the WPF Formatting Service. Every method inspects either the active HTML element under the caret or the editor's overall command state, and answers a single yes/no or scalar question — is the selection bold?, is the caret inside a table?, can the user undo?. Host applications use it to drive toolbar button states, context-menu enable/disable logic, and event-driven UI such as the 2-Way Table Dialog. The service is reached through the StateQuery property on the editor (for example MyEditor.StateQuery.IsBold()).

Methods that ask about the active element walk up the DOM from the caret. For example IsTable() returns true only when the active element itself is the <table>, while IsActiveOrAncestorElementTable() also returns true when the caret is inside a cell or any nested element of the table. Pick the variant that matches the question you are asking.

The three QueryCommand* methods are thin wrappers over MSHTML's queryCommandEnabled, queryCommandState, and queryCommandValue. They are provided for advanced scenarios where the strongly-typed helpers do not cover the command name you need.

Namespace: SpiceLogic.HtmlEditor.WPF.Models.Services
Assembly: SpiceLogic.HtmlEditor.WPF
Inheritance: WPF.Models.Services.IStateQueryService : IStateQueryServiceBase : IStateQueryService (SpiceLogic.HtmlEditor.Abstractions.Services) : IDisposable. The WPF surface re-declares GetActiveForeColor and GetActiveHighlightColor to return System.Windows.Media.Color instead of System.Drawing.Color — the rest of the interface is inherited unchanged.

In every example below, MyEditor is a WpfHtmlEditor instance declared in XAML (namespace SpiceLogic.HtmlEditor.WPF).

GetActiveHtmlElement()

Returns the MSHTML element under the caret. Use this as the starting point for any DOM-level inspection that the strongly-typed helpers do not cover.

Syntax
IHTMLElement GetActiveHtmlElement();
Parameters

None.

Returns

The active mshtml.IHTMLElement, or null when the document is empty or not ready.

Example
var element = MyEditor.StateQuery.GetActiveHtmlElement();

if (element != null)

{

    System.Diagnostics.Debug.WriteLine($"Caret tag: {element.tagName}");

}

IsImage()

Indicates whether the active HTML element is an image (<img>).

Syntax
bool IsImage();
Parameters

None.

Returns

true when the active element is an image; otherwise false.

Example
// Show an "Image Properties..." menu only when the caret targets an image.

ImagePropsMenuItem.Visibility = MyEditor.StateQuery.IsImage()

    ? Visibility.Visible : Visibility.Collapsed;

IsHyperLink()

Indicates whether the active HTML element itself is an anchor (<a>). This method does not walk up the DOM — use IsActiveOrAncestorElementHyperLink() when the caret may sit inside text wrapped by a link.

Syntax
bool IsHyperLink();
Parameters

None.

Returns

true when the active element is an anchor; otherwise false.

Example
if (MyEditor.StateQuery.IsHyperLink())

{

    StatusText.Text = "Anchor selected";

}

IsTable()

Indicates whether the active HTML element itself is a <table>. Does not climb ancestors.

Syntax
bool IsTable();
Parameters

None.

Returns

true when the active element is a table; otherwise false.

Remarks

To detect a caret anywhere inside a table (cells, paragraphs, spans nested in cells), call IsActiveOrAncestorElementTable() instead.

Example
TableBordersButton.IsEnabled = MyEditor.StateQuery.IsTable();

IsActiveOrAncestorElementTable()

Indicates whether the active element or any of its ancestors is a <table>. Returns true even when the caret is inside a <span>, paragraph, or table cell. Designed for the 2-Way Table Dialog entry check.

Syntax
bool IsActiveOrAncestorElementTable();
Parameters

None.

Returns

true when the caret sits inside any table; otherwise false.

Example
// Enable the "Edit Table..." menu only when the caret is inside a table.

EditTableMenuItem.IsEnabled = MyEditor.StateQuery.IsActiveOrAncestorElementTable();

GetCurrentTable()

Returns a populated TableElement describing the nearest enclosing <table> ancestor of the current caret, or null when the caret is not inside any table. TableElement is the model object used by the 2-Way Table Dialog — host code can pass it to a custom edit dialog, mutate properties, and commit changes via TableElement.UpdateTheActiveHtmlElement().

Syntax
TableElement GetCurrentTable();
Parameters

None.

Returns

The enclosing TableElement, or null when the caret is not inside any table.

Remarks

CSS round-trip caveat: getters fall back to computed style when an HTML attribute is missing. Setters write only to HTML attributes and inline style — they never edit external stylesheets. For fully CSS-driven tables, prefer editing the stylesheet directly.

Example
var table = MyEditor.StateQuery.GetCurrentTable();

if (table != null)

{

    table.BorderWidth = 1;

    table.UpdateTheActiveHtmlElement();

}

IsTableCell()

Indicates whether the active HTML element is a table cell (<td> or <th>).

Syntax
bool IsTableCell();
Parameters

None.

Returns

true when the active element is a table cell; otherwise false.

Example
CellPropertiesMenuItem.Visibility = MyEditor.StateQuery.IsTableCell()

    ? Visibility.Visible : Visibility.Collapsed;

CanMergeTableCells()

Indicates whether the current selection spans two or more adjacent cells in a way that allows a merge operation. Suitable for enabling a "Merge Cells" toolbar button or context-menu item.

Syntax
bool CanMergeTableCells();
Parameters

None.

Returns

true when the selection covers mergeable cells; otherwise false.

Example
MergeCellsButton.IsEnabled = MyEditor.StateQuery.CanMergeTableCells();

IsJustifyLeft()

Indicates whether the active paragraph is left-justified.

Syntax
bool IsJustifyLeft();
Parameters

None.

Returns

true when the paragraph is left-aligned; otherwise false.

Example
JustifyLeftButton.IsChecked = MyEditor.StateQuery.IsJustifyLeft();

IsJustifyRight()

Indicates whether the active paragraph is right-justified.

Syntax
bool IsJustifyRight();
Parameters

None.

Returns

true when the paragraph is right-aligned; otherwise false.

Example
JustifyRightButton.IsChecked = MyEditor.StateQuery.IsJustifyRight();

IsJustifyCenter()

Indicates whether the active paragraph is center-justified.

Syntax
bool IsJustifyCenter();
Parameters

None.

Returns

true when the paragraph is center-aligned; otherwise false.

Example
JustifyCenterButton.IsChecked = MyEditor.StateQuery.IsJustifyCenter();

IsOverWriteMode()

Indicates whether the editor is in overwrite (Insert key) mode, where typing replaces the character at the caret instead of inserting before it.

Syntax
bool IsOverWriteMode();
Parameters

None.

Returns

true when overwrite mode is active; otherwise false.

Example
// Drive a status-bar "OVR" indicator from the caret state.

OverwriteStatusText.Text = MyEditor.StateQuery.IsOverWriteMode() ? "OVR" : "INS";

IsOrderedList()

Indicates whether the active element is inside an ordered list (<ol>).

Syntax
bool IsOrderedList();
Parameters

None.

Returns

true when the caret sits inside an ordered list; otherwise false.

Example
OrderedListButton.IsChecked = MyEditor.StateQuery.IsOrderedList();

IsUnorderedList()

Indicates whether the active element is inside an unordered list (<ul>).

Syntax
bool IsUnorderedList();
Parameters

None.

Returns

true when the caret sits inside an unordered list; otherwise false.

Example
UnorderedListButton.IsChecked = MyEditor.StateQuery.IsUnorderedList();

IsStrikeThrough()

Indicates whether the active element is strike-through.

Syntax
bool IsStrikeThrough();
Parameters

None.

Returns

true when strike-through is in effect; otherwise false.

Example
StrikeThroughButton.IsChecked = MyEditor.StateQuery.IsStrikeThrough();

IsSuperscript()

Indicates whether the active element is rendered as superscript.

Syntax
bool IsSuperscript();
Parameters

None.

Returns

true when superscript is in effect; otherwise false.

Example
SuperscriptButton.IsChecked = MyEditor.StateQuery.IsSuperscript();

IsSubscript()

Indicates whether the active element is rendered as subscript.

Syntax
bool IsSubscript();
Parameters

None.

Returns

true when subscript is in effect; otherwise false.

Example
SubscriptButton.IsChecked = MyEditor.StateQuery.IsSubscript();

IsUnderline()

Indicates whether the active element is underlined.

Syntax
bool IsUnderline();
Parameters

None.

Returns

true when underline is in effect; otherwise false.

Example
UnderlineButton.IsChecked = MyEditor.StateQuery.IsUnderline();

IsItalic()

Indicates whether the active element is italic.

Syntax
bool IsItalic();
Parameters

None.

Returns

true when italic is in effect; otherwise false.

Example
ItalicButton.IsChecked = MyEditor.StateQuery.IsItalic();

IsBold()

Indicates whether the active element is bold.

Syntax
bool IsBold();
Parameters

None.

Returns

true when bold is in effect; otherwise false.

Example
// Sync a toolbar Bold button with the caret state.

BoldButton.IsChecked = MyEditor.StateQuery.IsBold();

GetActiveFontFamilyName()

Returns the CSS font-family name applied to the active element.

Syntax
string GetActiveFontFamilyName();
Parameters

None.

Returns

The active font-family string, or an empty string when none is set.

Example
FontFamilyComboBox.Text = MyEditor.StateQuery.GetActiveFontFamilyName();

GetActiveFontSize()

Returns the CSS font-size of the active element as a string. The value reflects whatever CSS unit is in effect on that element (px, em, named sizes, etc.).

Syntax
string GetActiveFontSize();
Parameters

None.

Returns

The active font-size, or an empty string when none is set.

Example
FontSizeComboBox.Text = MyEditor.StateQuery.GetActiveFontSize();

GetFontSizeFromElement(IHTMLElement element)

Returns the CSS font-size of a specific HTML element. Helpful when you have an element reference from GetElementFromPoint() or DOM traversal and want its size without first making it the active element.

Syntax
string GetFontSizeFromElement(IHTMLElement element);
Parameters
NameTypeDescription
elementmshtml.IHTMLElementThe element to inspect.
Returns

The CSS font-size of element, or an empty string when none is set.

Example
var active = MyEditor.StateQuery.GetActiveHtmlElement();

string size = MyEditor.StateQuery.GetFontSizeFromElement(active);

System.Diagnostics.Debug.WriteLine($"Active element font-size: {size}");

GetActiveForeColor()

Returns the foreground (text) color of the active element. The WPF surface overrides the base interface to return a WPF System.Windows.Media.Color instead of System.Drawing.Color, so the value is directly assignable to WPF brushes.

Syntax
Color GetActiveForeColor();
Parameters

None.

Returns

A System.Windows.Media.Color value.

Example
var color = MyEditor.StateQuery.GetActiveForeColor();

ForeColorSwatch.Fill = new System.Windows.Media.SolidColorBrush(color);

GetActiveHighlightColor()

Returns the background highlight color of the active element. The WPF surface overrides the base interface to return a WPF System.Windows.Media.Color instead of System.Drawing.Color.

Syntax
Color GetActiveHighlightColor();
Parameters

None.

Returns

A System.Windows.Media.Color value.

Example
var color = MyEditor.StateQuery.GetActiveHighlightColor();

HighlightSwatch.Fill = new System.Windows.Media.SolidColorBrush(color);

IsYouTubeVideo()

Indicates whether the active element is an embedded YouTube video (an iframe whose src attribute points to a YouTube embed URL).

Syntax
bool IsYouTubeVideo();
Parameters

None.

Returns

true when the active element is a YouTube embed; otherwise false.

Example
EditVideoMenuItem.Visibility = MyEditor.StateQuery.IsYouTubeVideo()

    ? Visibility.Visible : Visibility.Collapsed;

QueryCommandEnabled(string commandName)

Reports whether the given MSHTML edit command is currently enabled. Thin wrapper over document.queryCommandEnabled.

Syntax
bool QueryCommandEnabled(string commandName);
Parameters
NameTypeDescription
commandNamestringAn MSHTML command name (e.g. "Bold", "Undo", "InsertOrderedList").
Returns

true when the command is enabled for the current state.

Example
BoldButton.IsEnabled = MyEditor.StateQuery.QueryCommandEnabled("Bold");

QueryCommandState(string commandName)

Reports whether the given MSHTML edit command is currently in the "on" state for the active element. Thin wrapper over document.queryCommandState.

Syntax
bool QueryCommandState(string commandName);
Parameters
NameTypeDescription
commandNamestringAn MSHTML command name.
Returns

true when the command state is on for the active element.

Example
ItalicButton.IsChecked = MyEditor.StateQuery.QueryCommandState("Italic");

QueryCommandValue(string commandName)

Returns the current value of the given MSHTML edit command. Thin wrapper over document.queryCommandValue. Useful for commands that carry a string or numeric value (font name, font size, foreground color expressed as RGB).

Syntax
object QueryCommandValue(string commandName);
Parameters
NameTypeDescription
commandNamestringAn MSHTML command name.
Returns

The command value as boxed in MSHTML. Cast as appropriate.

Example
var fontName = MyEditor.StateQuery.QueryCommandValue("FontName") as string;

FontFamilyComboBox.Text = fontName ?? string.Empty;

CanUndo()

Indicates whether the editor has an action available to undo.

Syntax
bool CanUndo();
Parameters

None.

Returns

true when an undo is available; otherwise false.

Example
UndoButton.IsEnabled = MyEditor.StateQuery.CanUndo();

CanRedo()

Indicates whether the editor has an action available to redo.

Syntax
bool CanRedo();
Parameters

None.

Returns

true when a redo is available; otherwise false.

Example
RedoButton.IsEnabled = MyEditor.StateQuery.CanRedo();

CanCut()

Indicates whether the current selection can be cut to the clipboard.

Syntax
bool CanCut();
Parameters

None.

Returns

true when Cut is allowed; otherwise false.

Example
CutButton.IsEnabled = MyEditor.StateQuery.CanCut();

CanCopy()

Indicates whether the current selection can be copied to the clipboard.

Syntax
bool CanCopy();
Parameters

None.

Returns

true when Copy is allowed; otherwise false.

Example
CopyButton.IsEnabled = MyEditor.StateQuery.CanCopy();

CanPaste()

Indicates whether clipboard content can currently be pasted into the editor.

Syntax
bool CanPaste();
Parameters

None.

Returns

true when Paste is allowed; otherwise false.

Example
PasteButton.IsEnabled = MyEditor.StateQuery.CanPaste();

CanDelete()

Indicates whether a Delete-key action would consume content (i.e. there is a selection or content to the right of the caret).

Syntax
bool CanDelete();
Parameters

None.

Returns

true when Delete is allowed; otherwise false.

Example
DeleteButton.IsEnabled = MyEditor.StateQuery.CanDelete();

IsActiveElementHeaderTitle()

Indicates whether the active element is an HTML heading (<h1>..<h6>).

Syntax
bool IsActiveElementHeaderTitle();
Parameters

None.

Returns

true when the active element is a heading; otherwise false.

Example
HeadingComboBox.Visibility = MyEditor.StateQuery.IsActiveElementHeaderTitle()

    ? Visibility.Visible : Visibility.Collapsed;

GetActiveHeaderTitleNumber()

Returns the level (1-6) of the heading that contains the caret. Returns 0 when the caret is not inside a heading.

Syntax
int GetActiveHeaderTitleNumber();
Parameters

None.

Returns

The heading level (1 through 6), or 0.

Example
int level = MyEditor.StateQuery.GetActiveHeaderTitleNumber();

HeadingComboBox.Text = level == 0 ? "Normal" : $"Heading {level}";

GetElementFromPoint(Point pt)

Returns the HTML element at the specified point relative to the editor's client area. Designed for hit-testing in pointer-event handlers (right-click context menus, drag-and-drop targets). The point is a System.Drawing.Point; convert from a WPF System.Windows.Point when wiring up WPF mouse events.

Syntax
HtmlElement GetElementFromPoint(Point pt);
Parameters
NameTypeDescription
ptSystem.Drawing.PointCoordinates relative to the editor's client area.
Returns

The element at that point, or null when none.

Example
private void Editor_MouseRightButtonDown(object sender, MouseButtonEventArgs e)

{

    var p = e.GetPosition(MyEditor);

    var el = MyEditor.StateQuery.GetElementFromPoint(new System.Drawing.Point((int)p.X, (int)p.Y));

    if (el != null) StatusText.Text = $"Right-clicked: <{el.TagName.ToLower()}>";

}

SetTableManipulator(ITableManipulator tableManipulator)

Injects a custom ITableManipulator implementation that GetCurrentTable() and related table queries use when populating TableElement. Advanced extension point; the default manipulator wired in by the editor is sufficient for the built-in 2-Way Table Dialog.

Syntax
void SetTableManipulator(ITableManipulator tableManipulator);
Parameters
NameTypeDescription
tableManipulatorITableManipulatorThe custom manipulator to use.
Returns

None.

Example
// Advanced: inject a custom table manipulator before the editor wires its default.

MyEditor.StateQuery.SetTableManipulator(new MyCustomTableManipulator());

IsActiveOrAncestorElementHyperLink()

Indicates whether the active element or any of its ancestors is a hyperlink. Use this — rather than IsHyperLink() — when the caret may sit inside a <span> or <b> nested inside an <a>.

Syntax
bool IsActiveOrAncestorElementHyperLink();
Parameters

None.

Returns

true when the caret is inside a hyperlink; otherwise false.

Example
// Enable an "Edit Link..." menu item whenever the caret is inside an anchor.

EditLinkMenuItem.IsEnabled = MyEditor.StateQuery.IsActiveOrAncestorElementHyperLink();

Dispose()

Inherited from IDisposable. Called by the editor control during teardown to release the underlying MSHTML command target; host applications normally do not invoke this directly.

Syntax
void Dispose();
Parameters

None.

Returns

None.

Example
// Disposing the WpfHtmlEditor disposes its StateQuery as a side effect,

// so host code does not typically call this directly:

MyEditor.Dispose();
Last updated on May 14, 2026