Iterate Through TreeViewItems
Telerik RadTreeView class inherits from ItemsControl. The Items collection of the ItemsControl is a collection of data objects, not from RadTreeViewItems. There is a very important concept about the items and item containers. When you bind an ItemsControl you have your data items populating the Items collection of the control. The containers are the visual presentations of those data items (in this case the containers are the RadTreeViewItems). Containers are not created automatically when the ItemsControl is bound, but are created asynchronously and only when needed. For example in the case with the TreeView, the containers are not being created until their parent is expanded.
So how you can get the container from the data item? Or in this case - how to get the RadTreeViewItem from your data object which you receive when traversing the Items collection?
There are several helper methods that can be used. Each ItemsControl has a Property named ItemContainerGenerator. It is of type ItemContainerGenerator. This class has the following methods that can help you in this case:
- DependencyObject.ContainerFromIndex(int index) - returns the Container for the given index from the Items collection.
- DependencyObject.ContainerFromItem(object item) - returns the Container for the given data item from the Items collection.
So here is an example about how to get access to all of the Containers in the RadTreeView:
The item container may be null if it isn't still generated from the runtime. That's why you should access the containers when your control is generated and added to the visual tree.
this.Loaded += new RoutedEventHandler( IterateTreeViewItems_Loaded );
AddHandler Me.Loaded, AddressOf IterateTreeViewItems_Loaded
private void IterateTreeViewItems_Loaded( object sender, RoutedEventArgs e )
{
this.GetContainers();
}
private void GetContainers()
{
// gets all nodes from the TreeView
Collection<RadTreeViewItem> allTreeContainers = GetAllItemContainers( this.radTreeView );
// gets all nodes (recursively) for the first node
RadTreeViewItem firstNode = this.radTreeView.ItemContainerGenerator.ContainerFromIndex( 0 ) as RadTreeViewItem;
if ( firstNode != null )
{
Collection<RadTreeViewItem> firstNodeContainers = GetAllItemContainers( firstNode );
}
}
private Collection<RadTreeViewItem> GetAllItemContainers( Telerik.Windows.Controls.ItemsControl itemsControl )
{
Collection<RadTreeViewItem> allItems = new Collection<RadTreeViewItem>();
for ( int i = 0; i < itemsControl.Items.Count; i++ )
{
// try to get the item Container
RadTreeViewItem childItemContainer = itemsControl.ItemContainerGenerator.ContainerFromIndex( i ) as RadTreeViewItem;
// the item container maybe null if it is still not generated from the runtime
if ( childItemContainer != null )
{
allItems.Add( childItemContainer );
Collection<RadTreeViewItem> childItems = GetAllItemContainers( childItemContainer );
foreach ( RadTreeViewItem childItem in childItems )
{
allItems.Add( childItem );
}
}
}
return allItems;
}
Private Sub IterateTreeViewItems_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.GetContainers()
End Sub
Private Sub GetContainers()
' gets all nodes from the TreeView '
Dim allTreeContainers As Collection(Of RadTreeViewItem) = GetAllItemContainers(Me.radTreeView)
' gets all nodes (recursively) for the first node '
Dim firstNode As RadTreeViewItem = TryCast(Me.radTreeView.ItemContainerGenerator.ContainerFromIndex(0), RadTreeViewItem)
If firstNode IsNot Nothing Then
Dim firstNodeContainers As Collection(Of RadTreeViewItem) = GetAllItemContainers(firstNode)
End If
End Sub
Private Function GetAllItemContainers(ByVal itemsControl As Telerik.Windows.Controls.ItemsControl) As Collection(Of RadTreeViewItem)
Dim allItems As New Collection(Of RadTreeViewItem)()
For i As Integer = 0 To itemsControl.Items.Count - 1
' try to get the item Container '
Dim childItemContainer As RadTreeViewItem = TryCast(itemsControl.ItemContainerGenerator.ContainerFromIndex(i), RadTreeViewItem)
' the item container maybe null if it is still not generated from the runtime
If childItemContainer IsNot Nothing Then'
allItems.Add(childItemContainer)
Dim childItems As Collection(Of RadTreeViewItem) = GetAllItemContainers(childItemContainer)
For Each childItem As RadTreeViewItem In childItems
allItems.Add(childItem)
Next
End If
Next
Return allItems
End Function