Simple RadContextMenu Example Request

6 posts, 1 answers
  1. Dave
    Dave avatar
    17 posts
    Member since:
    Jul 2005

    Posted 06 Oct 2011 Link to this post

    I've read through the docs and forum and I am clearly coming up short on how to associate a specific RadContextMenu with a specific item type in the RadTreeView.

    In the tree, I am programmatically creating RadTreeViewItem items.

    The items are either "folders" or "projects".

    When a user right-clicks a folder, I'd like to show a one-item menu "Delete Folder". When they click a project, they should get a one-item menu "Delete Project".

    I created a simple menu off the tree which shows the "Delete Folder" regardless of the item type selected (no surprise, but at least I made some progress):

     

    <telerik:RadContextMenu.ContextMenu
      
        <telerik:RadContextMenu
      
            <telerik:RadMenuItem Header="Delete Folder" x:Name="popDeleteFolder" /> 
      
        </telerik:RadContextMenu
      
    </telerik:RadContextMenu.ContextMenu

    I am capturing this in my VB code behind, so I know its all hooked up and working correctly.

    So, the question is, how can I (easily) determine the item "type" and show the appopriate menu? Alternatively, I assume I need to use DataTemplates, etc (which I am NOT currently using) to hook this all up.

    The samples and demo (with all the binding this and that) is definitely more advanced than I am used to.

    Can you show me a simple sample that just associates a given menu with a given item type?

    Thanks!
    Dave

  2. paaland
    paaland avatar
    17 posts
    Member since:
    Jun 2009

    Posted 07 Oct 2011 Link to this post

    What I do is to databind the context menu to a property that returns different menues depending on a property (itemtype) on the node in the tree.

    <telerikNavigation:RadTreeView x:Name="ItemTree" >
               <telerikNavigation:RadTreeView.ItemTemplate>               
                   <telerik:HierarchicalDataTemplate ItemsSource="{Binding Children}" telerik:ContainerBinding.ContainerBindings="{StaticResource ContainerBindings}">                   
                       <Grid HorizontalAlignment="Stretch">
                           <Grid.ColumnDefinitions>
                               <ColumnDefinition Width="Auto"/>
                               <ColumnDefinition Width="Auto"/>
                               <ColumnDefinition Width="*"/>
                           </Grid.ColumnDefinitions>
                           <telerikNavigation:RadContextMenu.ContextMenu>
                               <telerikNavigation:RadContextMenu ItemsSource="{Binding ContextMenu}"/>
                           </telerikNavigation:RadContextMenu.ContextMenu>
                           <Viewbox Height="16" Stretch="UniformToFill" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,5,0" Grid.Column="0" ToolTipService.ToolTip="{Binding ToolTip, Mode=OneWay}">
                               <ContentControl Content="{Binding NodeIcon}"/>
                           </Viewbox>
                           <TextBlock Text="{Binding ItemName, Mode=TwoWay}" Grid.Column="1" ToolTipService.ToolTip="{Binding ToolTip, Mode=OneWay}" />                       
                           <Rectangle HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Transparent" Grid.Column="2"/>                           
                       </Grid>                   
                   </telerik:HierarchicalDataTemplate>
               </telerikNavigation:RadTreeView.ItemTemplate>           
           </telerikNavigation:RadTreeView>

    The ContextMenu property of the items bound to the tree is something like this:

    public List<RadMenuItem> ContextMenu
    {
        get
        {
            List<RadMenuItem> contextMenu = new List<RadMenuItem>();
     
            switch (this.ItemTypeID)
            {
                //Group
                case 0:
                    contextMenu.Add(new RadMenuItem() { Header = ApplicationStrings.GroupNew, CommandParameter = "GroupNew" });
                    contextMenu.Add(new RadMenuItem() { Header = ApplicationStrings.GroupRefresh, CommandParameter = "GroupRefresh" });
                    break;
     
                ...
                ...
            }
             
            //All item types can be copy/pasted
            contextMenu.Add(new RadMenuItem() { Header = ApplicationStrings.CopyItem, CommandParameter = "CopyItem" });
            contextMenu.Add(new RadMenuItem() { Header = ApplicationStrings.CutItem, CommandParameter = "CutItem" });
            contextMenu.Add(new RadMenuItem() { Header = ApplicationStrings.PasteItem, CommandParameter = "PasteItem" });
             
            return contextMenu;
        }
    }

    I have similar properties for Icon in order to display different node images depending on the item type.
  3. DevCraft banner
  4. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2891 posts

    Posted 07 Oct 2011 Link to this post

    Hi Paal and Dave,

     Could you please examine this demo and let us know if the suggested approach in it fits in your scenarios ? Thank you for your cooperation in advance.

    All the best,
    Petar Mladenov
    the Telerik team

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

  5. Dave
    Dave avatar
    17 posts
    Member since:
    Jul 2005

    Posted 07 Oct 2011 Link to this post

    Thanks Paal - that has really helped me better understand this.

    Petar - your demo simply has too much in it to easily understand what I am trying to accomplish. Its almost like you need to break down the large demo into smaller ones showing specific features - rather than rolling so much into one. Its hard to determine which parts of the demo are actually needed to resolve my issue.

    I've now blended information from both the sample code from Paal and the demo into a working solution.

    The last problem I have is when the user hovers over and then right-clicks a treeitem (they have NOT left-clicked it, so it is not selected) I have no way to determine which tree item was the source. The tree view's selecteditem is nothing (since they never actually left-click selected an item).

    I looked at trying to capture a MouseRight click event but saw no way to do this.

    Can anyone help me determine which item in the tree is being hovered over when the user right-clicks to bring up a context menu?

    Thanks!
    Dave
  6. Answer
    paaland
    paaland avatar
    17 posts
    Member since:
    Jun 2009

    Posted 07 Oct 2011 Link to this post

    Dave: What I do is first to hook ut the routed event for clicking on a menu item. This is done in the constructor of the view that has the treeview in it:

    this.ItemTree.AddHandler(RadMenuItem.ClickEvent, new RoutedEventHandler(OnContextMenuClick));

    Then in the OnContextMenuClick event handler I can figure out which tree node has activated the context menu like this:

    private void OnContextMenuClick(object sender, RoutedEventArgs args)
    {
           RadMenuItem menuItem = ((RadRoutedEventArgs)args).OriginalSource as RadMenuItem;
           RadTreeViewItem treeViewItem = FindParentOfType<RadTreeViewItem>(menuItem);
      
           ItemNode itemNode = (ItemNode)treeViewItem.DataContext;
      
           switch (menuItem.CommandParameter.ToString().ToLower())
           {
                    case "command1":
                        //handle context menu command1
                        break;
              
                    case "command2":
                        //handle context menu command2
                        break;
         }
    }
     
    private static T FindParentOfType<T>(UIElement element) where T : UIElement
     {
                if (element == null) return null;
     
                DependencyObject parent =
                    Telerik.Windows.RoutedEvent.GetLogicalParent(element) ??
                    VisualTreeHelper.GetParent(element);
     
                while ((parent != null) && !(parent is T))
                {
                    parent =Telerik.Windows.RoutedEvent.GetLogicalParent(parent) ??  VisualTreeHelper.GetParent(parent);
                }
     
                return (T)parent;
    }

    ItemNode is my class that represents a tree node. The treeview is bound to an observablecollection of those.
  7. Dave
    Dave avatar
    17 posts
    Member since:
    Jul 2005

    Posted 07 Oct 2011 Link to this post

    Awesome - FindParentOfType was the key.

    I've got it working perfectly.

    Thanks a bunch!
    Dave
Back to Top
DevCraft banner