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

Convert Self-Referencing Data Model to Hierarchical Data Structure in RadTreeListView

Environment

Product RadTreeListView for WPF
Version 2021.3.914

Description

How to convert self-referencing data model to a hierarchical data structure that can be used in list controls which support hierarchy (like RadTreeListView).

Solution

The following example shows a common self-referencing hierarchy data model.

    public class DataItem
    {
       public string Id { get; set; }
       public string Text { get; set; }
           public int? ParentId { get; set; }
    }

The new hierarchical data model can look like this:

    public class HierarchicalDataItem
    {
       public string Id { get; set; }
       public string Text { get; set; }
       public ObservableCollection<HierarchicalDataItem> Children { get; set; }
    }

The conversion can be done using an algorithm similar to this one:

        public ObservableCollection<HierarchicalDataItem> ConvertFlatCollectionToHierarchy(List<DataItem> flatSource)
    {
        var result = new ObservableCollection<HierarchicalDataItem>();
        var idToItemDict = new Dictionary<int, HierarchicalDataItem>();

        foreach (DataItem originalItem in flatSource)
        {
            var convertedItem = new HierarchicalDataItem();
            convertedItem.Children = new ObservableCollection<HierarchicalDataItem>();
            convertedItem.Id = originalItem.Id;
            convertedItem.Text = originalItem.Text;
            idToItemDict[convertedItem.Id] = convertedItem;

            if (originalItem.ParentId == null)
            {
                result.Add(convertedItem);
            }
            else
            {
                if (idToItemDict.ContainsKey(originalItem.ParentId.Value))
                {
                    idToItemDict[originalItem.ParentId.Value].Children.Add(convertedItem);
                }
            }

        }
        return result;
    }

The following example shows the method usage:

        var originalData = new List<DataItem>();
    originalData.Add(new DataItem() { Text = "Item 1", Id = 1, ParentId = null });
    originalData.Add(new DataItem() { Text = "Item 2", Id = 2, ParentId = null });
    originalData.Add(new DataItem() { Text = "Item 3", Id = 3, ParentId = null });
    originalData.Add(new DataItem() { Text = "Item 1.1", Id = 4, ParentId = 1 });
    originalData.Add(new DataItem() { Text = "Item 1.2", Id = 5, ParentId = 1 });
    originalData.Add(new DataItem() { Text = "Item 2.1", Id = 6, ParentId = 2 });
    originalData.Add(new DataItem() { Text = "Item 2.2", Id = 7, ParentId = 2 });
    originalData.Add(new DataItem() { Text = "Item 3.1", Id = 8, ParentId = 3 });
    originalData.Add(new DataItem() { Text = "Item 1.1.1", Id = 9, ParentId = 4 });
    originalData.Add(new DataItem() { Text = "Item 3.1.1", Id = 10, ParentId = 8 });

    ObservableCollection<HierarchicalDataItem> convertedCollection = ConvertFlatCollectionToHierarchy(originalData);

    this.treeListView.ItemsSource = convertedCollection;
In this article