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
| Name | Type | Description |
|---|---|---|
| element | mshtml.IHTMLElement | The 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
| Name | Type | Description |
|---|---|---|
| commandName | string | An 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
| Name | Type | Description |
|---|---|---|
| commandName | string | An 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
| Name | Type | Description |
|---|---|---|
| commandName | string | An 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
| Name | Type | Description |
|---|---|---|
| pt | System.Drawing.Point | Coordinates 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
| Name | Type | Description |
|---|---|---|
| tableManipulator | ITableManipulator | The 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();