How to: Position a Custom Context Menu in a RichTextBox

 

This example shows how to position a custom context menu for a RichTextBox.

When you implement a custom context menu for a RichTextBox, you are responsible for handling the placement of the context menu. By default, a custom context menu is opened at the center of the RichTextBox.

To override the default placement behavior, add a listener for the ContextMenuOpening event. The following example shows how to do this programmatically.

            richTextBox.ContextMenuOpening += new ContextMenuEventHandler(richTextBox_ContextMenuOpening);

The following example shows an implementation the corresponding ContextMenuOpening event listener.

        // This method is intended to listen for the ContextMenuOpening event from a RichTextBox.
        // It will position the custom context menu at the end of the current selection.
        void richTextBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            // Sender must be RichTextBox.
            RichTextBox rtb = sender as RichTextBox;
            if (rtb == null) return;

            ContextMenu contextMenu = rtb.ContextMenu;
            contextMenu.PlacementTarget = rtb;

            // This uses HorizontalOffset and VerticalOffset properties to position the menu,
            // relative to the upper left corner of the parent element (RichTextBox in this case).
            contextMenu.Placement = PlacementMode.RelativePoint;

            // Compute horizontal and vertical offsets to place the menu relative to selection end.
            TextPointer position = rtb.Selection.End;

            if (position == null) return;
            
            Rect positionRect = position.GetCharacterRect(LogicalDirection.Forward);
            contextMenu.HorizontalOffset = positionRect.X;
            contextMenu.VerticalOffset = positionRect.Y;

            // Finally, mark the event has handled.
            contextMenu.IsOpen = true;
            e.Handled = true;
        }

RichTextBox Overview
TextBox Overview

Show: