New to Telerik UI for WPFStart a free 30-day trial

Bind RadTreeView to Hierarchical Data from WCF Service and Use Load on Demand

Updated on Sep 24, 2025

The purpose of this tutorial is to show you how to populate RadTreeView with hierarchical data loaded from WCF service.

Here is a simple treeview declaration:

XAML
	<UserControl.Resources>
	
	    <example:HierarchicalDataSource x:Key="Source" />
	
	    <HierarchicalDataTemplate x:Key="NodeTemplate"
	        ItemsSource="{Binding Children}">
	        <TextBlock Text="{Binding Text}"/>
	    </HierarchicalDataTemplate>
	
	</UserControl.Resources>
	
	<Grid x:Name="LayoutRoot" Background="White">
	
	    <telerik:RadTreeView x:Name="radTreeView" Margin="8"
	        ItemsSource="{Binding Source={StaticResource Source}}"
	        ItemTemplate="{StaticResource NodeTemplate}"/>
	
	</Grid>

The web service will return an observable collection with objects of type TableItem. Here is the TableItem structure:

C#
	public class TableItem
	{
	    public TableItem()
	    {
	        this.Children = new List<TableItem>();
	    }
	    public int Id
	    {
	        get;
	        set;
	    }
	    public int ParentId
	    {
	        get;
	        set;
	    }
	    public string Text
	    {
	        get;
	        set;
	    }
	    public List<TableItem> Children
	    {
	        get;
	        set;
	    }
	}

Now that you have the basis set up, it's time to go on. First you should create your data source object. Add a new class named HierarchicalDataSource which derives from ObservableCollection of TableItem.

C#
	public class HierarchicalDataSource : ObservableCollection<TableItem>
	{
	    public HierarchicalDataSource()
	    {
	    }
	}

Next, you need to add a reference to the WCF service and load the data. You also need a list that holds all items that come from the web service result.

C#
	public class HierarchicalDataSource : ObservableCollection<TableItem>
	{
	    // This list holds all the items that come from the web service result
	    private List<TableItem> unsortedList = new List<TableItem>();
	    public HierarchicalDataSource()
	    {
	        SampleWcfServiceClient serviceClient = new SampleWcfServiceClient();
	        serviceClient.LoadHierarchicalDataCompleted += new EventHandler<LoadHierarchicalDataCompletedEventArgs>( serviceClient_LoadHierarchicalDataCompleted );
	        serviceClient.LoadHierarchicalDataAsync();
	    }
	    private void serviceClient_LoadHierarchicalDataCompleted( object sender, LoadHierarchicalDataCompletedEventArgs e )
	    {
	        // transfer all the items from the result to the unsorted list
	        foreach ( TableItem item in e.Result )
	        {
	            TableItem genericItem = new TableItem()
	            {
	                Text = item.Text,
	                Id = item.Id,
	                ParentId = item.ParentId
	            };
	            this.unsortedList.Add( genericItem );
	        }
	        // Get all the first level nodes.
	        var rootNodes = this.unsortedList.Where( x => x.ParentId == 0 );
	        // Foreach root node, get all its children and add the node to the HierarchicalDataSource.
	        // see below how the FindChildren method works
	        foreach ( TableItem node in rootNodes )
	        {
	            this.FindChildren( node );
	            this.Add( node );
	        }
	    }
	}

Add the FindChildren() method to the HierarchicalDataSource file. It will find all child nodes by a given item.

C#
	private void FindChildren( TableItem item )
	{
	    // find all the children of the item
	    var children = unsortedList.Where( x => x.ParentId == item.Id && x.Id != item.Id );
	    // add the child to the item's children collection and call the FindChildren recursively, in case the child has children
	    foreach ( TableItem child in children )
	    {
	        // By not calling iteratively FindChildren() here we prevent
	        // the automatic loading of all items in the data
	        // source and load only the next level in the hierarchy
	        item.Children.Add( child );
	    }
	}

Add a public method named LoadItemChildren(). This method visits all current items and adds their direct children to the data source, if there are any.

C#
	public void LoadItemChildren( TableItem item )
	{
	    foreach ( TableItem i in item.Children )
	    {
	        FindChildren( i );
	    }
	}

Finally add an event handler in your treeview declaration for the Expanded event.

XAML
	<telerik:RadTreeView x:Name="radTreeView" Margin="8"
	    Expanded="radTreeView_Expanded"
	    ItemsSource="{Binding Source={StaticResource Source}}"
	    ItemTemplate="{StaticResource NodeTemplate}"/>

Switch to the code-behind and the following code to handle the event.

C#
	private void radTreeView_Expanded( object sender, Telerik.Windows.RadRoutedEventArgs e )
	{
	    Telerik.Windows.Controls.RadTreeView tree = sender as Telerik.Windows.Controls.RadTreeView;
	    RadTreeViewItem item = e.OriginalSource as RadTreeViewItem;
	    if ( ( tree != null ) && ( item != null ) )
	    {
	        // Load the next level from the data hierarchy
	        HierarchicalDataSource source = this.Resources[ "Source" ] as HierarchicalDataSource;
	        TableItem ti = item.DataContext as TableItem;
	        if ( ( ti != null ) && ( source != null ) )
	        {
	            source.LoadItemChildren( ti );
	        }
	    }
	}

Here, you first get references to the treeview and the item that was expanded. Then, you get a reference to the hierarchical data source and call its LoadItemChildren() method and pass the value of the expanded item. What the method does is fetching the children of that data item via the web service and adding them as children of the treeview.

See Also

In this article
See Also
Not finding the help you need?
Contact Support