New to Telerik UI for Blazor? Download free 30-day trial

Treeview Data Binding

This article explains how to relate TreeView item features to properties of the data model. This is a prerequisite for successful data binding of the TreeView:

Item Features

The TreeView items have features that map to properties in the model. The following model uses property names that will work automatically, with no additional TreeView configuration:

public class TreeItem
{
    public int Id { get; set; }
    public string Text { get; set; }
    public bool HasChildren { get; set; }

    // ParenId for flat data
    public int? ParentId { get; set; }
    // OR
    // Items for hierarchical data
    public IEnumerable<TreeItem> Items { get; set; }

    public string ImageUrl { get; set; }
    public string Icon { get; set; }
    public string IconClass { get; set; }
    public string Url { get; set; }
}

The above model properties have the following meaning for the TreeView:

Property Description
Id A unique identifier. Required for binding to flat data.
Text Sets the item content as plain text. For rich content and nested components, use an item template
Item relations
HasChildren Determines whether the item has children, no matter if they are loaded or not. Required for binding to flat data and for load on demand. If true, the item will show an expand arrow. With hierarchical data, the TreeView renders expand icons based on Items, but HasChildren will take precedence.
ParentId Identifies the item's parent. Required for binding to flat data. Set to null for root items. Do not use ParentId with hierarhical data.
Items Defines the item's children. Required for binding to hierarchical data. The children's type can be different from the parent item type.
Graphics
ImageUrl Sets a URL to a raster image
Icon Defines a Telerik icon
IconClass Sets a CSS class for a custom font icon.
Navigation
Url If set, the TreeView will generate a link to another page in the app, or an external page.

Define only the model properties you need. If several image/icon properties have a value, the TreeView will use only one value in the following order of precedence: ImageUrl, Icon, IconClass.

TreeView Bindings

All TreeView item features map to model properties. The model properties can have different names in every application. That is why, the mappings between the model and the TreeView depend on TreeViewBinding tags.

Each TreeViewBinding tag exposes the following parameters that refer to model property names:

TreeViewBinding Parameter Default Value
IdField "Id"
TextField "Text"
Item relations
HasChildrenField "HasChildren"
ParentIdField (flat data) "ParentId"
ItemsField (hierarchical data) "Items"
Graphics
IconField "Icon"
IconClassField "IconClass"
ImageUrlField "ImageUrl"
Navigation
UrlField "Url"

It is possible to configure different bindings for different item levels. Usually one binding configuration is enough. For example, if the model properties are...

public class TreeItem
{
    public int UniqueID { get; set; }
    public string Description { get; set; }
    public bool HasChildren { get; set; }
    public IEnumerable<TreeItem> Children { get; set; }
}

... then the binding configuration should look like this:

<TelerikTreeView>
    <TreeViewBindings>
        <TreeViewBinding IdField="UniqueID" TextField="Description" ItemsField="Children" />
    </TreeViewBindings>
</TelerikTreeView>

If some model property names match the default ones in the table above, then there is no need to configure them in a TreeViewBinding.

If your model field names match any of the default names, the component will try to use them. For example, a field called Icon will try to produce a Telerik icon out of those values and that may not be what you want. If you want to override such behaviors, you can set IconField="someNonExistingField". You can read more about this here. This also applies to other fields too. Another example would be a field called Url - in case you want to perform navigation yourself through templates, you may want to set UrlField="someFakeField" so that the component does not navigate on its own.

Do not use ParentId with hierarhical data. This will confuse the TreeView that it is bound to flat data and the component may not render any items. If the model must have a ParentId property, set ParentIdField in the TreeViewBinding to a non-existent property.

Multiple Level Bindings

The TreeViewBinding tag has one more parameter - Level. It allows you to define different model properties for different TreeView levels.

Multiple level bindings can make the application more flexible. If you use hierarchical data binding, the children can even use a different model type from their parent.

Level also allows you to define a different ItemTemplate for different levels.

To define multiple bindings, add multiple TreeViewBinding tags and set their Level. Levels are zero-based.

Level defines a binding for a specific level of depth. If no Level is set, the bindings will apply to any level that does not have explicit settings. TreeViews with unknown item depth should have one TreeViewBinding without a Level.

How to use different model fields and binding settings for different levels

The third level will use the main data bindings settings that do not have a level specified

<TelerikTreeView Data="@FlatData" @bind-ExpandedItems="@ExpandedItems">
    <TreeViewBindings>
        <TreeViewBinding ParentIdField="Parent" />
        <TreeViewBinding Level="1" TextField="SecondText" ParentIdField="Parent" />
    </TreeViewBindings>
</TelerikTreeView>

@code {
    public IEnumerable<TreeItem> FlatData { get; set; }
    public IEnumerable<object> ExpandedItems { get; set; } = new List<TreeItem>();

    public class TreeItem
    {
        public int Id { get; set; }
        public string Text { get; set; }
        public string SecondText { get; set; }
        public int? Parent { get; set; }
        public bool HasChildren { get; set; }
    }

    protected override void OnInitialized()
    {
        LoadFlat();
        ExpandedItems = FlatData.Where(x => x.HasChildren == true).ToList();
    }

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

        for (int i = 1; i <= 4; i++)
        {
            items.Add(new TreeItem()
            {
                Id = i,
                Text = "Parent " + i,
                Parent = null,
                HasChildren = i < 3
            });
        }

        for (int i = 5; i < 15; i++)
        {
            items.Add(new TreeItem()
            {
                Id = i,
                SecondText = "Child " + i, //this is the field used at level 1 - it is a different field than at levels 0 and 2
                Parent = i < 10 ? 1 : 2,
                HasChildren = i == 5
            });
        }

        for (int i = 16; i < 20; i++)
        {
            items.Add(new TreeItem()
            {
                Id = i,
                Text = "Second Child " + i,
                Parent = 5
            });
        }

        FlatData = items;
    }
}

For better performance, define the same ParentIdField for all levels, when using flat data.

Next Steps

Learn the three different ways to provide data to a TreeView:

See Also

In this article