Adding New Items to the WPF Editor Toolbar

David is an integrations developer at a mid-sized finance firm. His team ships a WPF desktop application that the firm's relationship managers use to draft client letters - quarterly statements, portfolio rebalancing notes, KYC follow-ups. The letters go through a compliance reviewer before they reach the client, and every reviewer is tired of the same complaint: the closing disclosure paragraph keeps drifting. One letter has the 2024 wording, the next has a typo, a third forgot the regulator's reference number entirely.

David's manager hands him a small task with a big upside. "Put a button on the editor toolbar called Insert Compliance Disclosure. When the RM clicks it, drop in the approved paragraph at the caret. We'll keep the canonical text in our config service so legal can update it without a redeploy."

WPF HtmlEditor toolbar with a custom Insert Compliance Disclosure button next to the factory buttons

David is already using the WpfHtmlEditor control. He opens the documentation, sees the Toolbar1Items and Toolbar2Items collection properties, and realises this is a one-evening job. The factory toolbars stay exactly as they are; he just appends his own button as a content child.

<wpfHtmlEditor:WpfHtmlEditor x:Name="LetterEditor" Grid.Row="1">

    <wpfHtmlEditor:WpfHtmlEditor.Toolbar1Items>

        <Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"

                Click="InsertDisclosure_OnClick"

                ToolTip="Insert the approved compliance disclosure">

            Insert Disclosure

        </Button>

    </wpfHtmlEditor:WpfHtmlEditor.Toolbar1Items>

</wpfHtmlEditor:WpfHtmlEditor>

Borrowing the ToolBar.ButtonStyleKey style makes the new button look like it has always been there - same hover affordance, same padding, same icon-sized footprint. David's designer doesn't even need to be involved.

In code-behind, the click handler is three lines. He fetches the disclosure paragraph from the config service and asks the editor to insert it at the caret. The InsertHtml method takes care of focus, selection, and firing the HtmlChanged event so any bound dirty-flag lights up correctly.

private void InsertDisclosure_OnClick(object sender, RoutedEventArgs e)

{

    string disclosureHtml = _complianceConfig.GetCurrentDisclosureHtml();

    LetterEditor.Content.InsertHtml(disclosureHtml, keepSelected: false);

}
The disclosure paragraph dropped into the letter at the caret position

The first RM to try the build sends David a short message: "Beautiful. Can we also have one for Risk Warning?" He adds a second button next to the first in the same Toolbar1Items block, points it at a second config entry, and ships it the same afternoon.

A month later David's manager comes back with a new idea: the available disclosure paragraphs vary by jurisdiction, and they should appear dynamically based on the RM's country. David switches from a static XAML child to the Toolbar1ItemsSource dependency property, binds it to an ObservableCollection<Button> on his view model, and the toolbar now rebuilds itself whenever the selected jurisdiction changes.

<wpfHtmlEditor:WpfHtmlEditor Toolbar1ItemsSource="{Binding JurisdictionToolbarItems}" />
  • Toolbar1Items and Toolbar2Items accept any WPF controls as content children for static markup additions.
  • Toolbar1ItemsSource and Toolbar2ItemsSource are dependency properties for MVVM-style bound collections.
  • From the click handler, call editor.Content.InsertHtml(...) to drop HTML at the caret with the dirty event fired for you.
Last updated on May 15, 2026