Content menus shared across RichTextBoxes?

7 posts, 1 answers
  1. Joel
    Joel avatar
    14 posts
    Member since:
    Aug 2010

    Posted 27 May 2011 Link to this post

    Hi,


    I've encountered a weird behavior.  I am trying to hide certain parts (table and font formatting) of a RadRichTextBox's content menu using the "Use ContextMenuBuilder class" approach of this example: http://www.telerik.com/help/wpf/radrichtextbox-features-context-menu.html

    This is the class I created to hide certain parts of the context menu:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Telerik.Windows.Documents.UI.Extensibility;
    using Telerik.Windows.Documents.UI;
    using Telerik.Windows.Controls.RichTextBoxUI.Menus;
    using Telerik.Windows.Documents.Model;
    using Telerik.Windows.Controls;
     
     
    class CustomMenuBuilder : ContextMenuContentBuilder
    {
        private RadRichTextBox radRichTextBox;
     
        public CustomMenuBuilder(RadRichTextBox radRichTextBox)
            : base(radRichTextBox)
        {
            this.radRichTextBox = radRichTextBox;
        }
     
        protected override ContextMenuGroup CreateTableCommands()
        {
            ContextMenuGroup g = new ContextMenuGroup();
            return g;
        }
     
        protected override ContextMenuGroup CreateHyperlinkCommands(bool forExistingHyperlink)
        {
            ContextMenuGroup g = new ContextMenuGroup();
            return g;
        }
     
        protected override ContextMenuGroup CreateTextEditCommands()
        {
            ContextMenuGroup g = new ContextMenuGroup();
            return g;
        }
    }


    And I then set my RichTextBox to use that new Context menu in another class:

    ((Telerik.Windows.Controls.RichTextBoxUI.ContextMenu)rtb1.ContextMenu).ContentBuilder = new CustomMenuBuilder(rtb1);

    This works perfectly if you only have 1 RichTextBox you want to do this on.  The problem appears if you want to do this on many RichTextBoxes:

    ((Telerik.Windows.Controls.RichTextBoxUI.ContextMenu)rtb1.ContextMenu).ContentBuilder = new CustomMenuBuilder(rtb1);
    ((Telerik.Windows.Controls.RichTextBoxUI.ContextMenu)rtb2.ContextMenu).ContentBuilder = new CustomMenuBuilder(rtb2);
    ((Telerik.Windows.Controls.RichTextBoxUI.ContextMenu)rtb3.ContextMenu).ContentBuilder = new CustomMenuBuilder(rtb3);

    Now, if you right click and paste in rtb1 or rtb2, the text appears in rtb3 (the last RichTextBox for which we assigned the menu).  It seems that the 3 menus are pointing to the same instance even though they are all new CustomMenuBuilder  objects.  Any way of hiding context menu sections and having each menu related to the right RichTextBox?

    Thanks,

    -- Joel
  2. Iva Toteva
    Admin
    Iva Toteva avatar
    1319 posts

    Posted 31 May 2011 Link to this post

    Hi Joel,

    You are right, by default all rich text boxes share one and the same context menu and the code in your snippet is setting three different content menu builders to one and the same context menu, used by all rich text boxes.
    You can change this behavior by creating new context menus for each rich text box and then setting the ContentMenuBuilder of each one. Please refer to the code-snippet below.

    rtb1.ContextMenu = new Telerik.Windows.Controls.RichTextBoxUI.ContextMenu() { ContentBuilder = new CustomMenuBuilder(rtb1) };
    rtb2.ContextMenu = new Telerik.Windows.Controls.RichTextBoxUI.ContextMenu() { ContentBuilder = new CustomMenuBuilder(rtb2) };
    rtb3.ContextMenu = new Telerik.Windows.Controls.RichTextBoxUI.ContextMenu() { ContentBuilder = new CustomMenuBuilder(rtb3) };

    I hope this helps.


    Regards,
    Iva
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
  4. Joel
    Joel avatar
    14 posts
    Member since:
    Aug 2010

    Posted 31 May 2011 Link to this post

    That worked.  Thanks!

    -- Joel
  5. Robert
    Robert avatar
    271 posts
    Member since:
    Mar 2011

    Posted 22 Jun 2012 Link to this post

    I have noticed exactly the same behaviour with my project. It is as if all of the loaded RadRichTextBoxes are referncing the same RTB at the same time (only for certain scenarios).

    I use the RadDocking Control, where the document host has multiple panes loaded. Each pane then contains a RadRichTextBox.
    I would set some ContextMenu items from one RichTextBox and noticed that they were also appearing in the Context Menus of the other RichTextBoxes.

    I also have a RadRibbionMenu above the RadDocking control that contains various buttons which perform specific actions on the selected document. I find at times, when I try to perform an action on the given selected pane that is hosting a RichTextBox, it ends up being applied to one of the other host pane RichTextBoxes. This often happens when the panes have been located side by side rather than grouped with tabs.
    I guess changing the layout of the docking panes alters the panes some how.

    Rob


  6. Iva Toteva
    Admin
    Iva Toteva avatar
    1319 posts

    Posted 26 Jun 2012 Link to this post

    Hello Rob,

    By default only one instance of RadContextMenu is created and used for all RadRichTextBox instances in the application. If you would like to change this behavior, you can mark your custom context menu with the following attribute:

    [PartCreationPolicy(CreationPolicy.NonShared)]
    [CustomContextMenu]
    public class NonSharedContextMenu : ContextMenu
    {
    }

    This ensures that MEF will instantiate different context menus for all rich text boxes in the application.

    Please, let us know if that does not solve the problem.

    Greetings,
    Iva Toteva
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  7. Robert
    Robert avatar
    271 posts
    Member since:
    Mar 2011

    Posted 04 Jul 2012 Link to this post

    Hi,

    Thanks for getting back to me. I'm not using a custom ContextMenu. I add a new Menu Item when the ContextMenu_Showing event is triggered.

    private void ContextMenu_Showing(object sender, ContextMenuEventArgs e)
    {
    //Add menu item to data context
    RadMenuItem addPriceMenuItem = new RadMenuItem()
    {
    Header = "Set Price",
    Icon = new System.Windows.Controls.Image() { Source = new BitmapImage(new Uri("Icons/Spec-Editor-Menu/sterling_pound_currency_50.png", UriKind.Relative))},
    Tag = products[products.Count - 1]
    };
    addPriceMenuItem.Click += this.SetPriceMenuItem_Click;
    ContextMenuGroup customContextMenuGroup = new ContextMenuGroup();
    customContextMenuGroup.Add(addPriceMenuItem);
    e.ContextMenuGroupCollection.Add(customContextMenuGroup);
    }


  8. Answer
    Robert
    Robert avatar
    271 posts
    Member since:
    Mar 2011

    Posted 04 Jul 2012 Link to this post

    Ok this is easily solved.
    When each RadRichTextBox loads I just create a new ContextMenu for each instance.

    //**** RadRichTextBox Context Menu *****
    private void ContextMenuSubscribe()
    {
        this.radRichTextBox.ContextMenu = new Telerik.Windows.Controls.RichTextBoxUI.ContextMenu();
        ContextMenu contextMenu = (ContextMenu)this.radRichTextBox.ContextMenu;
        contextMenu.Showing += this.ContextMenu_Showing;
    }

Back to Top
UI for WPF is Visual Studio 2017 Ready