Search code examples
wpfcontextmenuflowdocumentreader

Adding a menu item to a FlowDocumentReader ContextMenu


The FlowDocumentReader has two menu items in its ContextMenu, Copy and Select All. I'd like to add an additional MenuItem to it and have tried this:

    private void FlowDocumentReader_ContextMenuOpening(object sender, ContextMenuEventArgs e)
    {
        flowDocumentReader.ContextMenu.Items.Clear();
        MenuItem menuItem = new MenuItem();
        menuItem.Header = "Test";
        flowDocumentReader.ContextMenu.Items.Add(menuItem);
    }

additionally I've tried this:

    private void FlowDocumentReader_ContextMenuOpening(object sender, ContextMenuEventArgs e)
    {
        MenuItem menuItem = new MenuItem();
        menuItem.Header = "Test";
        flowDocumentReader.ContextMenu.Items.Add(menuItem);
    }

where I don't clear the items in the context menu and attempt to append it. Neither of these work.

I can create my own menu like so:

    private void FlowDocumentReader_ContextMenuOpening(object sender, ContextMenuEventArgs e)
    {
        MenuItem menuItem = new MenuItem();
        menuItem.Header = "Test";
        flowDocumentReader.ContextMenu.Items.Add(menuItem);
        e.Handled = true;
        ContextMenu menu = new ContextMenu();
        MenuItem a = new MenuItem();
        a.Header = "A";
        menu.Items.Add(a);
        MenuItem b = new MenuItem();
        b.Header = "B";
        menu.Items.Add(b);
        flowDocumentReader.ContextMenu.Items.Clear();
        flowDocumentReader.ContextMenu = menu;
        menu.IsOpen = true;
    }

And that'll show up, but what I'd like to have is the Copy and Select All menu items as well as A and B.

Ideas?


Solution

  • The solution I arrived at was to simply recreate those MenuItems on the new Menu and cancel the display of the built-in ContextMenu that is normally displayed. There are a number of built-in ApplicationCommands which can be incorporated into your own custom ContextMenu and the implementation of this is quite straightforward.

    Assume that I've got a ContextMenu created from some method, GetContextMenu(), the following event handler rejects the opening of the built-in ContextMenu and substitutes the one returned from the call to GetContextMenu() and adds in the Copy command (Select All is similar).

    private void flowDocumentReader_ContextMenuOpening(object sender, ContextMenuEventArgs e)
    {
       e.Handled = true;  // keeps the built-in one from opening
       ContextMenu myMenu = GetContextMenu();
       MenuItem copyMenuItem = new MenuItem();
       copyMenuItem.Command = ApplicationCommand.Copy;
       copyMenuItem.CommandTarget = myFlowDocument;
       myMenu.Items.Add(copyMenuItem);
       ShowMenu(myMenu);
    }
    
    private void ShowMenu(ContextMenu menu)
    {
       menu.Placement = PlacementMode.MousePoint;
       menu.PlacementRectangle = new Rect(0.0, 0.0, 0.0, 0.0);
       menu.IsOpen = true;
    }