Replacing the default Dialogs

    The WinForms HTML Editor ships with a full set of built-in dialogs - Insert Image, Insert Table, Insert Hyperlink, and more - so a document can be assembled without writing a single dialog yourself. Those dialogs use standard Windows Forms styling, which may not match a host application's custom theme, ribbon, or color scheme, and sometimes you need a field or a validation step the built-in dialog does not offer. Replacing one does not mean forking the editor's source: each dialog is exposed as a swappable service, so you can drop in your own WinForms form and leave everything else about the editor unchanged. This page shows how that hand-off works and what your custom dialog needs to implement.

    The hand-off point

    The editor exposes every built-in dialog through a single service hung off the control: editor.Dialog, typed as IDialogService. That service has nine properties, one per dialog, and each property has a setter. Assigning a new instance replaces the default for the lifetime of the editor; leaving a property alone keeps the factory dialog.

    Overview diagram of the SpiceLogic WinForms HTML Editor Dialog service exposing nine replaceable dialog properties (Image, Hyperlink, Table, and others) for hosts to override with branded UI.
    Overview diagram of the SpiceLogic WinForms HTML Editor Dialog service exposing nine replaceable dialog properties (Image, Hyperlink, Table, and others) for hosts to override with branded UI.

    The nine interfaces all live in SpiceLogic.HtmlEditor.WinForms.Models.Dialogs, and every one of them extends a single base contract from SpiceLogic.HtmlEditor.Abstractions.Dialogs:

    public interface IDialog : IDisposable {     DialogResult ShowDialog(); }
    Public Interface IDialog     Inherits IDisposable     Function ShowDialog() As DialogResult End Interface 

    That is the entire surface area. System.Windows.Forms.Form already returns DialogResult from its own ShowDialog() and already implements IDisposable, so a Form-derived class satisfies IDialog without writing a single extra line.

    InterfaceWhat the dialog editsProperty on editor.Dialog
    IImageDialogImage insert / propertiesImageDialog
    IHyperlinkDialogHyperlink insert / propertiesHyperlinkDialog
    ISearchDialogFind & ReplaceSearchDialog
    IStyleBuilderDialogCSS style builder for the body / selectionStyleBuilderDialog
    ISymbolDialogSpecial-character pickerSymbolDialog
    ITableDialogTable propertiesTableDialog
    ITableCellDialogTable-cell propertiesTableCellDialog
    IYouTubeVideoInsertDialogYouTube embedYouTubeVideoInsertDialog
    ISpellCheckerDialogModal spell-check windowSpellCheckerDialog

    Replacing the Image dialog

    To replace the Image dialog, create a Form (for example, BrandedImageDialog) and implement IImageDialog. That interface adds three members on top of ShowDialog(): an Element property of type ImageElement (the inbound and outbound image model), a bool IsLocalResourceSelectionDisabled hint, and a bool UseInlineStyleForDimensions hint that says "write width and height as inline CSS rather than as legacy attributes."

    using System.Windows.Forms; using SpiceLogic.HtmlEditor.Abstractions.Entities; using SpiceLogic.HtmlEditor.WinForms.Models.Dialogs;  public class BrandedImageDialog : Form, IImageDialog {     // --- IImageDialog members ---     public ImageElement Element { get; set; }     public bool IsLocalResourceSelectionDisabled { get; set; }     public bool UseInlineStyleForDimensions { get; set; }      public BrandedImageDialog()     {         InitializeComponent(); // designer-generated branded layout         this.Text = "Insert Image";         this.BackColor = System.Drawing.ColorTranslator.FromHtml("#0A2540"); // brand navy         this.ForeColor = System.Drawing.Color.White;         this.Font = new System.Drawing.Font("Segoe UI Variable", 10F);     }      protected override void OnLoad(System.EventArgs e)     {         base.OnLoad(e);         // The editor populates Element before calling ShowDialog().         // For a brand-new image, fields on Element are blank; for an existing         // selection, they are pre-filled. Map them onto your form controls.         txtUrl.Text = this.Element?.Src ?? string.Empty;         txtAlt.Text = this.Element?.Alt ?? string.Empty;         nudWidth.Value = this.Element?.Width ?? 0;         nudHeight.Value = this.Element?.Height ?? 0;         // Honor the editor's "no local files" mode (e.g., when authoring         // for the web and pasted file URIs are not wanted).         btnBrowse.Enabled = !this.IsLocalResourceSelectionDisabled;     }      private void btnOK_Click(object sender, System.EventArgs e)     {         // Push form values back into Element before closing.         this.Element.Src = txtUrl.Text;         this.Element.Alt = txtAlt.Text;         this.Element.Width = (int)nudWidth.Value;         this.Element.Height = (int)nudHeight.Value;         this.DialogResult = DialogResult.OK;         this.Close();     } }
    Imports System.Windows.Forms Imports SpiceLogic.HtmlEditor.Abstractions.Entities Imports SpiceLogic.HtmlEditor.WinForms.Models.Dialogs  Public Class BrandedImageDialog     Inherits Form     Implements IImageDialog     ' --- IImageDialog members ---     Public Property Element As ImageElement     Public Property IsLocalResourceSelectionDisabled As Boolean     Public Property UseInlineStyleForDimensions As Boolean      Public Sub New()         InitializeComponent() ' designer-generated branded layout         Me.Text = "Insert Image"         Me.BackColor = System.Drawing.ColorTranslator.FromHtml("#0A2540") ' brand navy         Me.ForeColor = System.Drawing.Color.White         Me.Font = New System.Drawing.Font("Segoe UI Variable", 10F)     End Sub      Protected Overrides Sub OnLoad(e As System.EventArgs)         MyBase.OnLoad(e)         ' The editor populates Element before calling ShowDialog().         ' For a brand-new image, fields on Element are blank; for an existing         ' selection, they are pre-filled. Map them onto your form controls.         txtUrl.Text = If(Element?.Src, String.Empty)         txtAlt.Text = If(Element?.Alt, String.Empty)         nudWidth.Value = If(Element?.Width, 0)         nudHeight.Value = If(Element?.Height, 0)         ' Honor the editor's "no local files" mode (e.g., when authoring         ' for the web and pasted file URIs are not wanted).         btnBrowse.Enabled = Not IsLocalResourceSelectionDisabled     End Sub      Private Sub btnOK_Click(sender As Object, e As System.EventArgs)         ' Push form values back into Element before closing.         Element.Src = txtUrl.Text         Element.Alt = txtAlt.Text         Element.Width = CInt(nudWidth.Value)         Element.Height = CInt(nudHeight.Value)         Me.DialogResult = DialogResult.OK         Me.Close()     End Sub End Class 

    One line in Form1_Load wires the dialog in:

    htmlEditor1.Dialog.ImageDialog = new BrandedImageDialog();
    htmlEditor1.Dialog.ImageDialog = New BrandedImageDialog()

    From the next click of the Image button onward, the editor calls into BrandedImageDialog. It populates Element with whatever the user selected (or a fresh ImageElement for an insert), sets the runtime hints from the matching UserOption values, calls ShowDialog(), and, if the result is OK, reads Element back and applies it to the document.

    Custom branded Image dialog shown at runtime in a legal-tech application, replacing the SpiceLogic WinForms HTML Editor default Insert Image dialog via the IImageDialog interface.
    Custom branded Image dialog shown at runtime in a legal-tech application, replacing the SpiceLogic WinForms HTML Editor default Insert Image dialog via the IImageDialog interface.

    The same pattern repeats for the other eight

    Each interface adds two or three domain-specific members. IHyperlinkDialog carries a HyperlinkElement Element, an IsLocalResourceSelectionDisabled flag, a RemoveLink flag (set on close when the user chooses "remove link"), and UseCtrlClickTooltipDefault. ITableDialog exposes a single TableElement Element. ISymbolDialog returns the picked character. Each interface's contract is small; see the source under Models/Dialogs/ for the exact members.

    The wiring at startup looks the same regardless of which dialogs you choose to replace:

    private void Form1_Load(object sender, EventArgs e) {     htmlEditor1.Dialog.ImageDialog = new BrandedImageDialog();     htmlEditor1.Dialog.HyperlinkDialog = new BrandedHyperlinkDialog();     htmlEditor1.Dialog.TableDialog = new BrandedTableDialog(htmlEditor1.Dialog.TableCellDialog);     htmlEditor1.Dialog.SearchDialog = new BrandedSearchWindow(); // SymbolDialog, StyleBuilderDialog, etc. left untouched -- the // factory versions are fine for those. }
    Private Sub Form1_Load(sender As Object, e As EventArgs)     htmlEditor1.Dialog.ImageDialog = New BrandedImageDialog()     htmlEditor1.Dialog.HyperlinkDialog = New BrandedHyperlinkDialog()     htmlEditor1.Dialog.TableDialog = New BrandedTableDialog(htmlEditor1.Dialog.TableCellDialog)     htmlEditor1.Dialog.SearchDialog = New BrandedSearchWindow()     ' SymbolDialog, StyleBuilderDialog, etc. left untouched -- the     ' factory versions are fine for those. End Sub

    Edge cases worth knowing

    The TableDialog default implementation takes a constructor argument of type ITableCellDialog (the table dialog can launch a cell-properties sub-dialog). If you replace both the table dialog and the cell dialog, pass the cell-dialog instance into the table-dialog constructor (or however your custom table form invokes its cell-properties button). Replacing only the table dialog and reusing the factory cell dialog is fine; retrieve it via htmlEditor1.Dialog.TableCellDialog.

    Runtime hints arrive on every ShowDialog() call, not just the first. Read them in OnLoad (or a setter that updates UI state), not in the constructor: the editor updates them between calls to reflect changes the host application made to editor.Options.

    Returning DialogResult.Cancel aborts the operation cleanly. The editor does not read back Element on Cancel; the document is left untouched.

    Side by side comparison of the SpiceLogic WinForms HTML Editor's default factory Insert Image dialog and a branded host-supplied replacement that matches the surrounding application UI.
    Side by side comparison of the SpiceLogic WinForms HTML Editor's default factory Insert Image dialog and a branded host-supplied replacement that matches the surrounding application UI.

    Shipping

    Replaced dialogs (for example the Image, Hyperlink, and Table dialogs) open windows that match the host application's look and feel. Factory dialogs stay in the binary and remain wired up for any interface you did not override. There is no fork of the editor's source, no copy-pasted controls, and no maintenance debt from customizing the editor. One Form per dialog, one property assignment per dialog, and the editor stays on the official upgrade path.

    Last updated on May 15, 2026

    Put this into practice.

    .NET WinForms HTML Editor Control ships with free C# and VB.NET sample projects and a 14-day evaluation.

    Prefer a guided look? Book a free live demo with our engineers - live on Zoom or Teams, never a chatbot.