TX Text Control .NET for WPF

Context Menus

Topic

Right-clicking in a WPF TextControl opens a built-in context menu that fits the clicked spot: a selection, a table, a header, a field, a comment or a selected image each get their own commands. Your code can hook into every menu before it opens, to add items, take items away, swap in a ContextMenu of your own or show nothing at all. The menus of misspelled words and of drawings have settings of their own, covered at the end.

The Opening Event

Immediately before a built-in menu appears, the TextControl raises TextContextMenuOpening. The handler receives TextContextMenuEventArgs of the TXTextControl.WPF namespace:

MemberPurpose
ContextMenuLocationThe part of the document the menu belongs to, a combination of ContextMenuLocation values
TextContextMenuThe menu about to be shown, a System.Windows.Controls.ContextMenu that you can change or replace
HorizontalOffset, VerticalOffsetThe distance of the menu from the top-left corner of the screen
Canceltrue shows no menu

The menu is an ordinary WPF ContextMenu: its Items take MenuItem and Separator objects, and each MenuItem has a Header and a Click event.

Add Items in the Event Handler

Connect the handler in XAML, next to the other attributes of the control in MainWindow.xaml:

<WPF:TextControl x:Name="textControl1"
                TextContextMenuOpening="TextControl1_TextContextMenuOpening" />

The WPF prefix is the namespace declaration xmlns:WPF="clr-namespace:TXTextControl.WPF;assembly=TXTextControl.WPF" of the window. In MainWindow.xaml.cs, the handler adds a Table Properties... item below a separator whenever the menu opens in a table:

using System.Windows;
using System.Windows.Controls;
using TXTextControl;
using TXTextControl.WPF;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void TextControl1_TextContextMenuOpening(object sender, TextContextMenuEventArgs e)
    {
        // Extend only the menus that open in a table
        if ((e.ContextMenuLocation & ContextMenuLocation.Table) != 0)
        {
            MenuItem propertiesItem = new MenuItem { Header = "Table Properties..." };
            propertiesItem.Click += (s, args) => textControl1.TableFormatDialog();

            e.TextContextMenu.Items.Add(new Separator());
            e.TextContextMenu.Items.Add(propertiesItem);
        }
    }
}

Keep the namespace of your project around the class.

The code works as follows:

  • using TXTextControl brings in ContextMenuLocation, and using TXTextControl.WPF the WPF TextControl and its event arguments.
  • The & test is true for every menu whose location includes Table.
  • MenuItem and Separator come from System.Windows.Controls and are appended to e.TextContextMenu.Items.
  • TableFormatDialog opens the built-in table dialog box. Built-in Dialog Boxes lists all of them.

The TX Words sample Context Menu, installed in %USERPROFILE%\Documents\TX Text Control 34.0.NET for WPF\CSharp\TX Words\Context Menu, extends the menu of a selected frame in this way. Its Frame Name... item opens a small window of the sample in which the user names the frame:

The Enter Frame Name window of the TX Words Context Menu sample for WPF over a selected drawing, with Smiley typed into the Frame name box.

Suppress or Replace a Menu

  • Show nothing. Set e.Cancel = true for the locations that should have no menu, for example ContextMenuLocation.PageMargin for the page margins.
  • Show your own menu. Assign a ContextMenu of your own, such as one defined in the resources of the window, to e.TextContextMenu. The reference allows the menu to be changed, extended or replaced entirely.
  • Take items away. Remove them from e.TextContextMenu.Items.

Assigning null to e.TextContextMenu is not the way to hide a menu: the reference states that the TextControl then uses system menu items. e.Cancel hides it.

Choose the Spelling Menu in XAML

With a spell checker connected through SpellChecker, a right-click on a misspelled word opens a spelling menu. The string property SpellCheckContextMenu selects it: (Default) for the built-in menu, (none) for no menu, or the resource key of a ContextMenu of your own. That menu lives in the Resources of the TextControl or of one of its parents in the logical tree:

<WPF:TextControl x:Name="textControl1" SpellCheckContextMenu="UserSpellCheckMenu">
    <WPF:TextControl.Resources>
        <ContextMenu x:Key="UserSpellCheckMenu">
            <MenuItem Header="Ignore" Click="Ignore_Click" />
        </ContextMenu>
    </WPF:TextControl.Resources>
</WPF:TextControl>

Ignore_Click is a handler of your own in MainWindow.xaml.cs. Spell Checking connects the spell checker, and Context Menus of TX Spell .NET for WPF fills such a menu with suggestions.

The Menu of Drawings

Shapes are edited in a TXDrawingControl. Its default menu, the ShapesContextMenu, is a ContextMenu with Cut, Copy, Paste, Bring to Front, Send to Back, Flip and further items for the selected shapes. See Text Frames and Shapes.

Context Menus and the Mini Toolbar

When ShowMiniToolbar enables it, the mini toolbar, a compact bar of formatting commands, can appear together with the menu when the user right-clicks a selection or an object. Toolbars and Mini Toolbars covers it.

Next Steps