blazor-docs/knowledge-base/contextmenu-treeview-items.md

5.2 KiB

title description type page_title slug position tags ticketid res_type
Add ContextMenu to the TreeView items How add ContextMenu to the TreeView items. how-to Add ContextMenu to the TreeView items contextmenu-kb-treeview-item 1508692 kb

Environment

Product ContextMenu for Blazor, TreeView for Blazor

Description

I would like to add the ContextMenu component to every item (node) in the TreeView.

Solution

The ContextMenu exposes an API to associate the component to any DOM element through the [ShowAsync]({%slug contextmenu-integration%}) method. You can use the oncontextmenu event of an HTML element in the [treeview item template]({%slug components/treeview/templates%}) to show the context menu by using the MouseEventArgs.

tip As of version 2.27, the TreeView exposes [OnItemContextMenu event]({%slug treeview-events%}#onitemcontextmenu) that you can use to integrate Telerik Context menu for the TreeView nodes. Here is an example of such a configuration - [Context menu for a TreeView node]({%slug contextmenu-integration%}#context-menu-for-a-treeview-node)

@* Use the oncontextmenu event of the HTML element to show the ContextMenu for the TreeView items *@

<TelerikContextMenu Data="@ContextMenuData"
                    @ref="ContextMenu"
                    SeparatorField="Separator"
                    TextField="Text"
                    IconField="Icon"
                    OnClick="@((ContextMenuItem item) => ClickHandler(item))">
</TelerikContextMenu>

<TelerikTreeView Data="@TreeData">
    <TreeViewBindings>
        <TreeViewBinding>
            <ItemTemplate>
                @{
                    TreeItem itm = context as TreeItem;
                    <div @oncontextmenu:preventDefault="true"
                          @oncontextmenu="@((MouseEventArgs e) => ShowContextMenu(e, itm))">
                        Node:
                        <strong>@itm.Text</strong>
                    </div>
                }
            </ItemTemplate>
        </TreeViewBinding>
    </TreeViewBindings>
</TelerikTreeView>

@code {
    private TelerikContextMenu<ContextMenuItem> ContextMenu { get; set; }
    TreeItem LastClickedItem { get; set; }

    private async Task ShowContextMenu(MouseEventArgs e, TreeItem item)
    {
        LastClickedItem = item;

        await ContextMenu.ShowAsync(e.ClientX, e.ClientY);
    }

    private void ClickHandler(ContextMenuItem item)
    {
        if (!string.IsNullOrEmpty(item.Text) && LastClickedItem != null)
        {
            Console.WriteLine($"Clicked on {item.CommandName} for {LastClickedItem.Text}");
        }

        LastClickedItem = null;
    }

    async Task NodeClick(TreeItem clickeNode)
    {
        //custom code here
    }

    // sample data

    public IEnumerable<TreeItem> TreeData { get; set; }
    public List<ContextMenuItem> ContextMenuData { get; set; }


    public class ContextMenuItem
    {
        public string Text { get; set; }
        public ISvgIcon Icon { get; set; }
        public bool Separator { get; set; }
        public string CommandName { get; set; }
    }

    public class TreeItem
    {
        public string Text { get; set; }
        public int Id { get; set; }
        public List<TreeItem> Items { get; set; } = new List<TreeItem>();
        public bool Expanded { get; set; }
        public bool HasChildren { get; set; }
    }

    protected override void OnInitialized()
    {
        LoadHierarchical();

        ContextMenuData = new List<ContextMenuItem>()
        {
            new ContextMenuItem
            {
                Text = "Info",
                Icon = SvgIcon.InfoCircle,
                CommandName = "info"
            },
            new ContextMenuItem
            {
                Separator = true
            },
            new ContextMenuItem
            {
                Text = "Delete",
                Icon = SvgIcon.Trash,
                CommandName = "delete"
            }
        };
    }

    private void LoadHierarchical()
    {
        List<TreeItem> roots = new List<TreeItem>() {
            new TreeItem { Text = "Item 1", Id = 1, Expanded = true, HasChildren = true },
            new TreeItem { Text = "Item 2", Id = 2, HasChildren = true }
        };

        roots[0].Items.Add(new TreeItem
        {
            Text = "Item 1 first child",
            Id = 3

        });

        roots[0].Items.Add(new TreeItem
        {
            Text = "Item 1 second child",
            Id = 4

        });

        roots[1].Items.Add(new TreeItem
        {
            Text = "Item 2 first child",
            Id = 5

        });

        roots[1].Items.Add(new TreeItem
        {
            Text = "Item 2 second child",
            Id = 6

        });

        TreeData = roots;
    }
}

Notes

At the time of writing, when you are using a template you cannot trigger a close of the ContextMenu, you can only close it if you click outside of it (there is an opened feature request for that in our public feedback portal) that contains a workaround.