private Type _editorContextMenuType;
private MethodInfo _editorContextMenuAddMenuItemsMethod;
private Type _textBoxBaseType;
private FieldInfo _textBoxBaseTextEditorField;
private PropertyInfo _contextMenuEventArgsUserInitiatedProperty;
_editorContextMenuType = typeof(TextBox).Assembly.GetType("System.Windows.Documents.TextEditorContextMenu+EditorContextMenu");
_editorContextMenuAddMenuItemsMethod = _editorContextMenuType.GetMethod("AddMenuItems",
BindingFlags.NonPublic |
BindingFlags.Instance);
_textBoxBaseType = typeof(TextBoxBase);
_textBoxBaseTextEditorField = _textBoxBaseType
.GetField("_textEditor", BindingFlags.NonPublic | BindingFlags.Instance);
_contextMenuEventArgsUserInitiatedProperty = typeof(ContextMenuEventArgs)
.GetProperty("UserInitiated",
BindingFlags.NonPublic |
BindingFlags.Instance);
public static void InjectIntoDefaultMenu(this TextBoxBase textBoxBase, ContextMenuEventArgs e, Action callBaseContextMenuOpening, params MenuItem[] items)
{
var contextMenu = (ContextMenu)Activator.CreateInstance(_editorContextMenuType, true);
textBoxBase.ContextMenu = contextMenu;
callBaseContextMenuOpening(e);
_editorContextMenuAddMenuItemsMethod.Invoke(contextMenu, new[]
{
_textBoxBaseTextEditorField.GetValue(textBoxBase),
_contextMenuEventArgsUserInitiatedProperty.GetValue(e, null)
});
if (contextMenu.Items.Count > 0 && items.Length > 0)
contextMenu.Items.Add(new Separator());
foreach (var item in items)
contextMenu.Items.Add(item);
}
Call this function on ContextMenuOpening of the TextBox like this:
this.InjectIntoDefaultMenu(e, p => base.OnContextMenuOpening(p), YOUMENUITEMS);
And you will see the default context menu incl. the spell checking menu if you use it and your menu item(s) at the end.