RadMenuItem.Items.Add

18 posts, 0 answers
  1. Glen
    Glen avatar
    5 posts
    Member since:
    Nov 2008

    Posted 27 Nov 2008 Link to this post

    Hi,

    I'm trying to dynamically alter the menu items in a RadMenu when another action occurs in my application.

    I've tried menu.Items.Clear() and menu.Items.Add(). Both result in an InvalidOperationException being thrown with the detail "Operation not supported on read-only collection.".

    Is there a way to alter the menu items at run time?

    Thanks,

    Glen
  2. Hristo
    Admin
    Hristo avatar
    832 posts

    Posted 28 Nov 2008 Link to this post

    Hi Glen,

    ItemsControl.Items collection is ReadOnly if you set ItemsSource property. So in order to change to Items you should alter the ItemsSource collection. If your collection implements INotifyCollectionChange just remove the item from your collection and the change will be reflected automaticaly in RadMenu.

    The other way is not to use ItemsSource. Just add items directly to Items property. This way the Items collection will not be readonly.

    If you need more help, we'll be glad to help.


    Best wishes,
    Hristo
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  3. DevCraft banner
  4. Glen
    Glen avatar
    5 posts
    Member since:
    Nov 2008

    Posted 30 Nov 2008 Link to this post

    Hi Hristo,

    Thanks for that info, I can add items now.

    My next stumbling block is that I don't know how to add sub items. My menu needs to be dynamic and will sometimes have 3 levels and sometimes have 4. So it will look something like:
    Country
            -> State
                -> Province
                    -> City

    But not all states have provinces. If there are no provinces I don't want to have that level appearing in the menu.

    So my code looks like:
    foreach (var country in Countries)
    {
        CountryMenu.Items.Add(country);
        foreach (var state in country.States)
        {
            // What goes here?
            CountryMenu.Items(Country).Items.Add(state); // This doesn't work. The item is the data object, not the RadMenuItem
        }
    }

    What I really need is a way to access the RadMenuitems, not the "Items" property so that I can add sub menu items.

    I could create an xml doc or even just bind to the data structure, but I don't know how I'd exclude the menu layer if a state has provinces. Also, I need the leaf node in the menu to be clickable, and if I can't trap the OnClick method of the leaf node, I'm not sure how I'd know it's been clicked.

    Do you have any thoughts how I could do this?

    Thanks,

    Glen
  5. Hristo
    Admin
    Hristo avatar
    832 posts

    Posted 01 Dec 2008 Link to this post

    Hi Glen,

    You can create an ObservableCollection from your data items and set them as ItemsSource on RadMenu. Then using HierarchicalDataTemplate you can create menu with unlimited nested leves.

    Here is an example:
    http://demos.telerik.com/silverlight/#Menu/DataSource

    Let me know if you need more help.


    Regards,
    Hristo
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  6. Glen
    Glen avatar
    5 posts
    Member since:
    Nov 2008

    Posted 01 Dec 2008 Link to this post

    Hi Hristo,

    I've seen that example and have implemented something similar. I was actually asking about something different.

    What I am trying to do is have a menu structure where the number of sub menus is not fixed. I need it to be fully dynamic. As far as I can tell, using HierarchicalDataTemplate means that you're setting a template so that the first level menu is always of a certain type, then the second level menu is always of a certain (different) type. It won't allow me the flexibility of having different sub menu structures.

    So what I want is:
    Menu
        -> Australia
            ->Victoria
                ->Melbourne
                -> Bendigo
            ->NSW
                ->Sydney
        -> UK
            ->London
            ->Leeds

    Do you see how under the Australia node there are two sub menu levels (state and city) where under the UK node there is only one level (city only).

    Glen
  7. Hristo
    Admin
    Hristo avatar
    832 posts

    Posted 02 Dec 2008 Link to this post

    Hi Glen,

    Using HierarchicalDataTemplate allows you to create hirarchy. HierarchicalDataTemplate have ItemsSource property that tells the item from where to get its children.

    I've attached a simple Page (UserControl) that demonstrate how to achieve dynamic MenuItems using classes like Country, State etc. You need to add it to existing project and add reference to our assemblies in order to run it.

    There is a problem with menuitem which is not loaded but change its items. This problem will be fixed for the next release - service pack 2 (due to middle of december). If you need it earlier just open a support ticket and I will send you the hotfix.

    If you need more help, I'll be glad to help


    Greetings,
    Hristo
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  8. Glen
    Glen avatar
    5 posts
    Member since:
    Nov 2008

    Posted 03 Dec 2008 Link to this post

    Hi Hristo,

    Thankyou for the information, but you are still misunderstanding what I'm actually asking. I've seen that sample before and it works fine. But it doesn't do what I want it to do.

    The example you have provided has dynamic menu data but I want dynamic menu structure.

    I want to allow one of the sub menus to not even have a "Province" item. So it goes Country->State->City. The other sub menu should have the province. It should go Country->State->Province->City. Can you see that the structure of the menu is different? In this case, there is not a single class hierarchy that can be bound to the menu ItemSource to provide this.

    Glen
  9. Hristo
    Admin
    Hristo avatar
    832 posts

    Posted 04 Dec 2008 Link to this post

    Hello Glen,

    Now I get what you want to achieve.

    They way I see it you can use generic collection and fill it with items that have Name and Items properties. This way you can use a single HierarchicalDataTemplate. I've attached an updated version of the sample illustrating this approach.

    The other way is to fill manually Items collection with RadMenuItem objects. This way you can take the RadMenuItem from Items collection with cast:

    foreach (var country in Countries)  
    {  
        RadMenuItem countryItem = new RadMenuItem() { Header = country.Name };  
        CountryMenu.Items.Add(countryItem);  
        foreach (var state in country.States)  
        {  
            RadMenuItem stateItem = new RadMenuItem() { Header = state.Name };  
            // Either use countryItem   
            countryItem.Items.Add(stateItem)  
            // Or if you don't have reference to countryItem you can take it like this;  
            //RadMenuItem countryItem = CountryMenu.Items[0] as RadMenuItem;  
        }  

    I hope this help.
    If you need more help, just drop me a line.


    Kind regards,
    Hristo
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  10. Glen
    Glen avatar
    5 posts
    Member since:
    Nov 2008

    Posted 07 Dec 2008 Link to this post

    Hi Hristo,

    Thanks for the information. I tried adding RadMenuitems but I was getting exceptions thrown when the menu was displayed.

    I like your suggestion of having a generic structure with Name and Item properties. I'll try that out.

    Thanks,

    Glen
  11. Bichitra
    Bichitra avatar
    34 posts
    Member since:
    Aug 2008

    Posted 16 Jan 2009 Link to this post

    Hi,

    I am getting the same problem here. I have created Menu. The main Menu contains  File, GoTo.

    I have created MenuItems dynamically using menu,Items.Add() method. As per my requirment.  on the acton of any in my page the child Items are different. So I need the remove the all child Items and Add new Items under GoTo Main Menu Item.

    When I am trying to  remove items under GoTo menu I am getting Parse error. on gotoItem.Items.Clear(); "AG_E_UNKNOWN_ERROR [Line: 1 Position: 1426]"
    RadMenu --> rdmenu

     

    RadMenuItem[] items = new RadMenuItem[rdmenu.Items.Count];

     

    rdmenu.Items.ToArray().CopyTo(items, 0);

     

     

    RadMenuItem gotoItem = (from menuItem in items

     

     

     

    where string.Compare(menuItem.Tag.ToString(), "Goto", StringComparison.InvariantCultureIgnoreCase) == 0

     

     

     

    select menuItem).Single();
    gotoItem.Items.Clear();

    Can u please help me to fix this issue.

    this is the error :"   at MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)\r\n   at MS.Internal.XcpImports.MethodEx(DependencyObject obj, String name)\r\n   at MS.Internal.XcpImports.Control_ApplyTemplate(Control control)\r\n   at System.Windows.Controls.Control.ApplyTemplate()\r\n   at Telerik.Windows.Controls.RadMenuItem.ChangeTemplate()\r\n   at Telerik.Windows.Controls.RadMenuItem.UpdateRole()\r\n   at Telerik.Windows.Controls.RadMenuItem.OnItemsChanged(NotifyCollectionChangedEventArgs e)\r\n   at System.Windows.Controls.ItemsControl.RaiseOnItemsChanged(NotifyCollectionChangedEventArgs e)\r\n   at System.Windows.Controls.ItemCollection.NotifyItemsControl(NotifyCollectionChangedEventArgs e)\r\n   at System.Windows.Controls.ItemCollection.RemoveAtImpl(Int32 index)\r\n   at System.Windows.PresentationFrameworkCollection`1.RemoveAt(Int32 index)\r\n   at System.Windows.Controls.ItemCollection.RemoveInternal(Object value)\r\n   at System.Windows.PresentationFrameworkCollection`1.Remove(T value)\r\n   at Xcel.Framework.RIA.ActivityManagement.CommonUI.Menu.notifyGotoMenuBuild_PropertyChanged(Object sender, PropertyChangedEventArgs e)"


     

     

  12. Hristo
    Admin
    Hristo avatar
    832 posts

    Posted 19 Jan 2009 Link to this post

    Hi Bichitra,

    Can you send us a simple project where we can investigate this issue. I have tried your case but there was no exception. Can you please check that you are using the latest version of our assemblies?
    Also do you put UIElements in the Header property of RadMenuItem or just strings?

    Waiting for your reply.

    Best wishes,
    Hristo
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  13. Bichitra
    Bichitra avatar
    34 posts
    Member since:
    Aug 2008

    Posted 19 Jan 2009 Link to this post

    Thanks for reply..

    I have used old version ..  I  put UIElements in the Header property .

    If there is no issues in new version so i will use that one.
    Is there any issue to add UIElements in the Header property ?

    Thanks
    Bichitra



  14. Hristo
    Admin
    Hristo avatar
    832 posts

    Posted 19 Jan 2009 Link to this post

    Hi Bichitra,

    Unfortunately there is an issue when Header is populated with UIElement. RadMenuItem Template contains ContentPresenter (or in some themes ContentControl) that is bound to Header property. When template is changed Silverlight doesn't clean this binding and when the new template is applied is tries to bind to the same UI object in the Header. But this object have parent and cannot have other parent until the first binding is removed so an exception is raised.

    We will try to find some workaround but for the moment I can think of one solution.
    Theme changing is happening when you remove all the Items. So instead of removing all items try to leave one item then add some new items and at the end remove the item that that was left.

    Like this:
    private void Button_Click(object sender, RoutedEventArgs e)  
    {  
        // Leave at least 1 item  
        for (int i = 1; i < menu1.Items.Count; i++)  
        {  
            menu1.Items.RemoveAt(1);  
        }  
     
        // Add the new items  
        menu1.Items.Add(new RadMenuItem() { Header = "asdasd" });  
     
        // remove the last item from the previos menu  
        menu1.Items.RemoveAt(0);  

    Here menu1 is root RadMenuItem.
    Let me know if this works for you.

    Best wishes,
    Hristo
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  15. Bichitra
    Bichitra avatar
    34 posts
    Member since:
    Aug 2008

    Posted 19 Jan 2009 Link to this post

    Hi,

    Thanks  for helping.. It is working now.

    Regards
    Bichitra
  16. Terry
    Terry avatar
    157 posts
    Member since:
    Jul 2009

    Posted 16 Oct 2009 Link to this post

    Hi:

    I've got a similar problem, but I want to bind to a menu structure defined in a SQL Server database.  I can write the SQL to retrieve the structure and add the items one by one, but is there a way to bind the menu directly to a single query resultset or is it necessary to iterate over the items and levels?  If this is possible, can you point me at an example?
  17. Kaloyan
    Admin
    Kaloyan avatar
    920 posts

    Posted 22 Oct 2009 Link to this post

    Hi Terry,

    There is no problem to bind your SQL collection data directly to the ItemsSource property of the RadMenuItem. You can check our online data binding example of the RadMenu showing this approach. Let us know if you need any further assistance.

    Best wishes,
    Kaloyan
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  18. Eduardo Lorenzo
    Eduardo Lorenzo avatar
    7 posts
    Member since:
    Mar 2010

    Posted 14 Apr 2010 Link to this post

    Hi,

    foreach (var country in Countries)  
    {  
        RadMenuItem countryItem = new RadMenuItem() { Header = country.Name };  
        CountryMenu.Items.Add(countryItem);  
        foreach (var state in country.States)  
        {  
            RadMenuItem stateItem = new RadMenuItem() { Header = state.Name };  
            // Either use countryItem   
            countryItem.Items.Add(stateItem)  
            // Or if you don't have reference to countryItem you can take it like this;  
            //RadMenuItem countryItem = CountryMenu.Items[0] as RadMenuItem;  
        }  

    This is well and good. Question tho, how do I add event handlers to the items?

    Thanks in advance!


  19. Kaloyan
    Admin
    Kaloyan avatar
    920 posts

    Posted 19 Apr 2010 Link to this post

    Hi Eduardo Lorenzo,

    RadMenuItem control is exposing a whole lot of events(Click, MouseLeftButtonDown...etc.etc) that can be used for adding event handlers. Exactly which event are you looking for?

    Kind regards,
    Kaloyan
    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.
Back to Top
DevCraft banner