Building a Custom Toolbar for the WPF HTML Editor
Yuki works at a Japanese ERP vendor in Osaka. Her team has just landed a redesign of the Sales Order module, and one of the visible pieces is a small notes panel that sits inside every order line. The product owner is firm: the notes panel must feel embedded, not bolted on. A full WYSIWYG toolbar with thirty buttons looming over a four-line text field is exactly the kind of thing he wants to avoid.
The requirement is clean: four commands only - Bold, Italic, Bullet List, and Hyperlink. Same height as the surrounding form labels. Same accent color as the rest of the new design system. Everything else should disappear.

Yuki has been using the WpfHtmlEditor for the document-editor screen elsewhere in the product, so she knows it has powerful built-in toolbars. The challenge is that for this embedded scenario she doesn't want any of them visible. She digs into the API and finds two things she needs: the built-in Toolbar1 and Toolbar2 are public properties on the editor (so she can collapse them), and every individual factory button is reachable through editor.ToolbarItemOverrider.ToolbarItems (so she can re-parent the four she wants).
Her XAML defines her own bare ToolBar directly above the editing surface, sized exactly to her design tokens.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ToolBar x:Name="CompactToolbar" Grid.Row="0" Height="28"
Background="{StaticResource Form.Accent}" />
<wpfHtmlEditor:WpfHtmlEditor x:Name="NotesEditor" Grid.Row="1"
Loaded="NotesEditor_OnLoaded" />
</Grid>The Loaded handler is where the actual surgery happens. Yuki collapses both built-in toolbars and then moves only the four buttons she needs into CompactToolbar.
private void NotesEditor_OnLoaded(object sender, RoutedEventArgs e)
{
NotesEditor.Toolbar1.Visibility = Visibility.Collapsed;
NotesEditor.Toolbar2.Visibility = Visibility.Collapsed;
var items = NotesEditor.ToolbarItemOverrider.ToolbarItems;
Adopt(items.Bold);
Adopt(items.Italic);
Adopt(items.UnOrderedList);
Adopt(items.Hyperlink);
}
private void Adopt(Control factoryControl)
{
if (factoryControl.Parent is ItemsControl previousHost)
previousHost.Items.Remove(factoryControl);
CompactToolbar.Items.Add(factoryControl);
}The buttons she moves are the actual factory ToggleButton and Button instances - not copies. Every wired click handler, every tooltip, every bit of context-sensitive state highlighting that the editor maintains internally still works. When the caret sits inside bold text, her adopted Bold toggle still lights up. The visual container changed; the wiring didn't.

The product owner reviews the result with her at the next demo. "That is what I had in my head," he says, and signs it off. A week later he asks Yuki to do the same trick on the Customer Contacts screen, this time with five buttons. She copy-pastes the helper method, swaps the buttons in the NotesEditor_OnLoaded handler, and it's done before lunch.
editor.Toolbar1.Visibilityandeditor.Toolbar2.Visibilityhide the built-in toolbar strips.editor.ToolbarItemOverrider.ToolbarItemsexposes every factory button so you can re-parent it into your ownToolBar.- Re-parented factory buttons keep their click handling and context-sensitive state intact.