Table Authoring Service

    The Content.TableAuthoringService property on WinFormHtmlEditor exposes an ITableAuthoringService instance. The service owns every table-editing operation the user can perform from the table toolbar -- insert column, insert row, delete row, merge cells, and the zero-border guideline overlay. Calling these members from code is the supported way to drive table editing from a custom toolbar, a hotkey, or an automation script.

    Namespace: SpiceLogic.HtmlEditor.Abstractions.Services.ElementAuthoring
    Assembly: SpiceLogic.HtmlEditor.Abstractions.dll
    Accessor: htmlEditor1.Content.TableAuthoringService

    The service implements IDisposable; the editor owns its lifetime, so customer code never needs to call Dispose directly.

    InsertColumn(InsertPositions position)

    Inserts a new column adjacent to the table cell that currently contains the caret.

    Syntax
    void InsertColumn(InsertPositions position);
    Parameters
    NameTypeDescription
    positionInsertPositionsBefore inserts the new column to the left of the caret column; After inserts it to the right.
    Remarks

    The caret must be inside a table cell. If it is not, the call is a no-op.

    Example
    using SpiceLogic.HtmlEditor.Abstractions;
    using SpiceLogic.HtmlEditor.Abstractions.Services.ElementAuthoring;
    
    ITableAuthoringService tables = htmlEditor1.Content.TableAuthoringService;
    // Insert a column to the right of the column under the caret.
    tables.InsertColumn(InsertPositions.After);
    Imports SpiceLogic.HtmlEditor.Abstractions
    Imports SpiceLogic.HtmlEditor.Abstractions.Services.ElementAuthoring
    
    Dim tables As ITableAuthoringService = htmlEditor1.Content.TableAuthoringService
    ' Insert a column to the right of the column under the caret.
    tables.InsertColumn(InsertPositions.After)

    DeleteColumn()

    Removes the column that contains the current cell from the table.

    Syntax
    void DeleteColumn();
    Remarks

    If the column is the only column in the table, the entire table is removed.

    Example
    if (MessageBox.Show("Delete this column?", "Confirm", MessageBoxButtons.YesNo) == DialogResult.Yes)
    {
        htmlEditor1.Content.TableAuthoringService.DeleteColumn();
    }
    If MessageBox.Show("Delete this column?", "Confirm", MessageBoxButtons.YesNo) Is DialogResult.Yes Then
        htmlEditor1.Content.TableAuthoringService.DeleteColumn()
    End If

    InsertRow(InsertPositions position)

    Inserts a new row adjacent to the row that contains the caret.

    Syntax
    void InsertRow(InsertPositions position);
    Parameters
    NameTypeDescription
    positionInsertPositionsBefore inserts the new row above the caret row; After inserts it below.
    Example
    // Hot-key handler for Ctrl+Enter -- append a new row below.
    private void AppendRow_Click(object sender, EventArgs e)
    {
        htmlEditor1.Content.TableAuthoringService.InsertRow(InsertPositions.After);
    }
    ' Hot-key handler for Ctrl+Enter -- append a new row below.
    Private Sub AppendRow_Click(sender As Object, e As EventArgs)
        htmlEditor1.Content.TableAuthoringService.InsertRow(InsertPositions.After)
    End Sub

    DeleteRow()

    Removes the row that contains the caret from the table.

    Syntax
    void DeleteRow();
    Remarks

    If the row is the only row in the table, the entire table is removed.

    Example
    htmlEditor1.Content.TableAuthoringService.DeleteRow();

    MergeSelectedCells()

    Merges the currently selected table cells into one. Styling on the resulting cell is inherited from the top-left source cell.

    Syntax
    void MergeSelectedCells();
    Remarks

    The call is a no-op when CanMergeCells() returns false or when EnableTableCellMerging is false. Guard custom toolbar buttons with CanMergeCells() so their enabled state matches.

    Example
    var tables = htmlEditor1.Content.TableAuthoringService;
    if (tables.CanMergeCells())
    {
        tables.MergeSelectedCells();
    }
    Dim tables = htmlEditor1.Content.TableAuthoringService
    
    If tables.CanMergeCells() Then
        tables.MergeSelectedCells()
    End If

    ShowGuidelinesForTablesWithZeroBorder(bool inBackground = false)

    Renders a dashed guideline overlay around every table whose border attribute is 0. The guideline is purely a visual aid -- it is not serialized into the document HTML.

    Syntax
    void ShowGuidelinesForTablesWithZeroBorder(bool inBackground = false);
    Parameters
    NameTypeDescription
    inBackgroundboolWhen true the DOM walk skips forcing layout, avoiding flicker when called from background-paint code paths. Default is false.
    Remarks

    The guideline CSS is customizable via Options.ZeroBorderTableGuidelineCss.

    Example
    // Toggle the guideline overlay from a toolbar button.
    htmlEditor1.Content.TableAuthoringService
        .ShowGuidelinesForTablesWithZeroBorder();

    HideGuidelinesOfTablesWithZeroBorder(bool inBackground = false)

    Removes the dashed guideline overlay added by ShowGuidelinesForTablesWithZeroBorder.

    Syntax
    void HideGuidelinesOfTablesWithZeroBorder(bool inBackground = false);
    Parameters
    NameTypeDescription
    inBackgroundboolPass the same value used in the matching ShowGuidelinesForTablesWithZeroBorder call.
    Example
    htmlEditor1.Content.TableAuthoringService
        .HideGuidelinesOfTablesWithZeroBorder();

    IsTableBorderZero(IHTMLElement tableElement)

    Tests whether a given <table> element has an effective border of zero -- via the border="0" attribute or via CSS that resolves to no visible border.

    Syntax
    bool IsTableBorderZero(IHTMLElement tableElement);
    Parameters
    NameTypeDescription
    tableElementmshtml.IHTMLElementThe MSHTML <table> element to test.
    Returns

    true when the table has no visible border; otherwise false.

    Example
    using mshtml;
    
    var tables = htmlEditor1.Content.TableAuthoringService;
    IHTMLElement selected = htmlEditor1.StateQuery.GetActiveHtmlElement();
    if (selected?.tagName == "TABLE" && tables.IsTableBorderZero(selected))
    {
        tables.ShowGuidelinesForTablesWithZeroBorder();
    }
    Imports mshtml
    
    Dim tables = htmlEditor1.Content.TableAuthoringService
    Dim selected As IHTMLElement = htmlEditor1.StateQuery.GetActiveHtmlElement()
    
    If selected?.tagName Is "TABLE" AndAlso tables.IsTableBorderZero(selected) Then
        tables.ShowGuidelinesForTablesWithZeroBorder()
    End If

    CanMergeCells()

    Reports whether the current selection covers two or more adjacent cells eligible for merging.

    Syntax
    bool CanMergeCells();
    Returns

    true when cells can be merged; otherwise false.

    Remarks

    Bind this to the Enabled of a custom Merge-Cells toolbar button inside SelectionChanged so the button greys out automatically when merging is not possible.

    Example
    htmlEditor1.SelectionChanged += (s, e) =>
    {
        mergeButton.Enabled = htmlEditor1.Content.TableAuthoringService.CanMergeCells();
    };

    GetTableManipulator()

    Returns the ITableManipulator state-query helper for the table currently under the caret. The manipulator exposes lower-level row/column DOM helpers used internally by the service.

    Syntax
    ITableManipulator GetTableManipulator();
    Returns

    An ITableManipulator scoped to the active table, or null when the caret is not inside a table.

    Example
    var manipulator = htmlEditor1.Content.TableAuthoringService.GetTableManipulator();
    if (manipulator != null)
    {
        Debug.WriteLine($"Caret is inside a table; CanMerge={manipulator.CanMerge()}");
    }
    Dim manipulator = htmlEditor1.Content.TableAuthoringService.GetTableManipulator()
    
    If manipulator IsNot Nothing Then
        Debug.WriteLine($"Caret is inside a table; CanMerge={manipulator.CanMerge()}")
    End If

    ResetTableManipulator()

    Discards the cached ITableManipulator so the next call to GetTableManipulator re-queries the MSHTML DOM. Call this after a programmatic edit you suspect invalidated the cached state -- for example, after replacing the document HTML wholesale.

    Syntax
    void ResetTableManipulator();
    Example
    htmlEditor1.Content.LoadBodyHtml("<table border=\"1\"><tr><td>A</td></tr></table>");
    htmlEditor1.Content.TableAuthoringService.ResetTableManipulator();

    SelectedCellBackgroundColor Property

    Gets or sets the background color used to highlight selected table cells on the editor surface. This is a UI-only highlight; it does not emit a background-color style on the cells themselves.

    Syntax
    Color SelectedCellBackgroundColor { get; set; }
    Property Value

    A System.Drawing.Color. The default is a light-blue overlay; pick any color that contrasts with your document background.

    Example
    using System.Drawing;
    
    htmlEditor1.Content.TableAuthoringService.SelectedCellBackgroundColor = Color.FromArgb(120, 255, 230, 0); // semi-transparent yellow
    
    Imports System.Drawing
    
    htmlEditor1.Content.TableAuthoringService.SelectedCellBackgroundColor = Color.FromArgb(120, 255, 230, 0) ' semi-transparent yellow

    EnableTableCellMerging Property

    Gets or sets whether the cell-merging feature is enabled. When false, MergeSelectedCells is a no-op and the editor suppresses any cell-selection UI.

    Syntax
    bool EnableTableCellMerging { get; set; }
    Property Value

    true to allow cell merging; false to disable it. This is initialized from Options.EnableTableCellMerge at startup.

    Example
    // Disable cell merging for a simplified authoring mode.
    htmlEditor1.Content.TableAuthoringService.EnableTableCellMerging = false;
    ' Disable cell merging for a simplified authoring mode.
    htmlEditor1.Content.TableAuthoringService.EnableTableCellMerging = False

    Last updated on May 14, 2026