[Solved] In DropDownTree, how can I prevent expand/collapse of items and only allow selection of leaf items

1 Answer 7 Views
DropDownTree
Bruno
Top achievements
Rank 1
Bruno asked on 02 Mar 2026, 04:17 PM

I want to use the new DropDownTree component to present a hierarchy of Menus > Tabs > Sections to allow a user to select a preferred default item on initial rendering of the main UI.

I would like to present everything fully expanded and prevent user from collapsing any node.

I furthermore would like to allow the user to only select a "leaf" item - that is, a node with no children.

How can I achieve this?

1 Answer, 1 is accepted

Sort by
0
Dimo
Telerik team
answered on 05 Mar 2026, 08:06 AM

Hello Bruno,

The desired behavior is possible to achieve with several of the DropDownTree events. Note thе Task.Delay() calls, which help the dropdown UI to revert to its "valid" state after "incorrect" user actions.

You can also hide the expand/collapse icons if you like.

<TelerikDropDownTree @ref="@DropDownTreeRef"
                     Data="@DropDownTreeData"
                     TValue="@int"
                     Value="@DropDownTreeValue"
                     ValueChanged="@DropDownTreeValueChanged"
                     ValueExpression="@(() => DropDownTreeValue)"
                     ExpandedItems="@DropDownTreeExpandedItems"
                     ExpandedItemsChanged="@DropDownTreeExpandedItemsChanged"
                     OnClose="@OnDropDownTreeClose"
                     OnItemRender="@OnDropDownTreeItemRender"
                     Width="300px">
</TelerikDropDownTree>

<style>
    .no-select {
        cursor: not-allowed;
        opacity: var(--kendo-disabled-opacity);
    }

    .no-select .k-treeview-toggle {
        pointer-events: none;
        /* display: none; */
    }
</style>

@code {
    private TelerikDropDownTree<int>? DropDownTreeRef { get; set; }
    private List<TreeItem> DropDownTreeData { get; set; } = new();

    private int DropDownTreeValue { get; set; } = 3;
    private bool ShouldNotCloseDropDownTree { get; set; }

    private IEnumerable<object> DropDownTreeExpandedItems { get; set; } = new List<TreeItem>();

    private async Task DropDownTreeExpandedItemsChanged(IEnumerable<object> newExpandedItems)
    {
        // This handler is necessary only for keyboard users.
        // Mouse users cannot collapse items due to the custom .k-treeview-toggle styles.

        // Force Blazor UI refresh to show back the collapsed items.
        // Increase the delay if necessary.
        await Task.Delay(100);

        DropDownTreeRef?.Refresh();
    }

    private async Task OnDropDownTreeClose(DropDownTreeCloseEventArgs args)
    {
        if (ShouldNotCloseDropDownTree)
        {
            args.IsCancelled = true;

            // Force Blazor UI refresh to show the previous valid selected item.
            // Increase the delay if necessary.
            await Task.Delay(100);

            DropDownTreeRef?.Refresh();

            ShouldNotCloseDropDownTree = false;
        }
    }

    private void OnDropDownTreeItemRender(DropDownTreeItemRenderEventArgs args)
    {
        var item = (TreeItem)args.Item;
        if (item.HasChildren)
        {
            args.Class = "no-select";
        }
    }

    private void DropDownTreeValueChanged(int newValue)
    {
        TreeItem? item = DropDownTreeData.FirstOrDefault(x => x.Id == newValue);

        if (item is not null && item.HasChildren)
        {
            ShouldNotCloseDropDownTree = true;
        }
        else
        {
            DropDownTreeValue = newValue;
        }
    }

    protected override void OnInitialized()
    {
        DropDownTreeData = LoadFlatData();

        DropDownTreeExpandedItems = DropDownTreeData.Where(x => x.HasChildren);
    }

    private int TreeLevels { get; set; } = 3;
    private int RootItems { get; set; } = 2;
    private int ItemsPerLevel { get; set; } = 2;
    private int IdCounter { get; set; }

    private List<TreeItem> LoadFlatData()
    {
        List<TreeItem> items = new List<TreeItem>();

        PopulateChildren(items, null, 1);

        return items;
    }

    private void PopulateChildren(List<TreeItem> items, int? parentId, int level)
    {
        var itemCount = level == 1 ? RootItems : ItemsPerLevel;
        for (int i = 1; i <= itemCount; i++)
        {
            var itemId = ++IdCounter;
            items.Add(new TreeItem()
            {
                Id = itemId,
                ParentId = parentId,
                HasChildren = level < TreeLevels,
                Text = $"Level {level} Item {i} Id {itemId}",
                Value = itemId
            });

            if (level < TreeLevels)
            {
                PopulateChildren(items, itemId, level + 1);
            }
        }
    }

    public class TreeItem
    {
        public int Id { get; set; }
        public int? ParentId { get; set; }
        public bool HasChildren { get; set; }
        public string Text { get; set; } = string.Empty;
        public int Value { get; set; }
    }
}

 

Regards,
Dimo
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
DropDownTree
Asked by
Bruno
Top achievements
Rank 1
Answers by
Dimo
Telerik team
Share this question
or