This is a migrated thread and some comments may be shown as answers.

Hierarchical Data Binding – Two Types at the Same Level

6 Answers 197 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Dave
Top achievements
Rank 1
Dave asked on 11 Sep 2009, 02:30 PM

I am trying to bind an object that has two collection and those collection has its own hierarchy below it.  I want to bind that object to tree control so that the two different collections appear at the same level in the tree.

 

Here is an example


public class Organization  
{  
    public List<People> Peeps { getset; }  
    public List<Equipment> Equip { getset; }  

I want People and Equipment to appear at the same level in the tree.  Is there a way to do it even if Organization is not at the top level of the hierarchy?

6 Answers, 1 is accepted

Sort by
0
Dave
Top achievements
Rank 1
answered on 11 Sep 2009, 08:44 PM
I figured it out.  I created a DataTemplateSelector and used the ItemTemplateSelector property of the

 

HierarchicalDataTemplate

0
Heather
Top achievements
Rank 1
answered on 23 Sep 2009, 12:26 PM
I have the same scenario and still haven't quite figured it out.  Given the Organization example how do you tell the tree to show two different nodes with the different collections?  I get how to use the template selector to show a different template for each child object type but not how to get the Peeps and Equip nodes.

Peeps
    Peep 1
    Peep 2
Equip
    Equip 1
    Equip 2
    ...
0
Dave
Top achievements
Rank 1
answered on 23 Sep 2009, 12:59 PM

Sorry (in advance) for the quick response…very busy.  I am assuming you know how to use Telerik’s HierarchicalDataTemplate.

Step 1) Create a DataTemplateSelector in the Telerik.Windows.Controls namespace:


namespace projectNamespace  
{  
    public class TreeNodeTemplateSelector : DataTemplateSelector  
    {  
        public DataTemplate PeepsTemplate { getset; }  
        public DataTemplate EquipTemplate { getset; }  
 
        public override DataTemplate SelectTemplate(object item, DependencyObject container)  
        {  
            if (item != null)  
            {  
                if (item is Peep)  
                {  
                    return PeepsTemplate;  
                }  
                else if (item is Equip)  
                {  
                    return EquipTemplate;  
                }  
            }  
 
            return null;              
        }  
    }  
}  
 

Step 2 optional) Create an interface in your view model.  This will be used to aggregate the two collections into one.

namespace projectNamespace  
{  
    public interface IOrgTreeNode  
    {  
       
    }  
}  
 

Step 3) Create a combined collection in the parent object that combines the two collections. If you did not create an interface you could use ‘object’ Note you could probably create a fancy LINQ query here but this is down and dirty.


private ObservableCollection<IOrgTreeNode> _treeNodes;  
        public ObservableCollection<IOrgTreeNode> TreeNodes  
        {  
            get 
            {  
                if (_treeNodes == null)  
                {  
                    _treeNodes = new ObservableCollection<IOrgTreeNode>();  
 
                    foreach (Peep p in _peeps)  
                    {  
                        _treeNodes.Add(p);  
                    }  
 
                    foreach (Equip e in _equips)  
                    {  
                        _treeNodes.Add(e);  
                    }                      
                }  
                return _treeNodes;  
            }  
        }  
 

Step 4) In Xaml set up your hierarchy templates.  Keep in mind order matters in Xaml, if you need to reference a  resource it must be before it in xaml.  That is why template selector comes after the two data templates it needs :

<Grid.Resources> 
<telerikCore:HierarchicalDataTemplate x:Key="_peepNode">  
                                <StackPanel Orientation="Horizontal">                                      
                                    <TextBlock Text="{Binding Path=Description}" VerticalAlignment="Center" /> 
                                </StackPanel> 
                            </telerikCore:HierarchicalDataTemplate> 
 
                            <telerikCore:HierarchicalDataTemplate x:Key="_equipNode">  
                                <StackPanel Orientation="Horizontal">                    
                                    <TextBlock Text="{Binding Path=Description}" VerticalAlignment="Center" /> 
                                </StackPanel> 
                            </telerikCore:HierarchicalDataTemplate> 
 
                            <local:TreeNodeTemplateSelector x:Key="TreeNodeTemplateSelector" PeepsTemplate="{StaticResource _peepNode}" EquipTemplate="{StaticResource _equipNode}" /> 
 
                            <telerikCore:HierarchicalDataTemplate x:Key="_orgNode" ItemsSource="{Binding Path=TreeNodes}" ItemTemplateSelector="{StaticResource TreeNodeTemplateSelector}">  
                                <StackPanel Orientation="Horizontal">  
                                    <TextBlock Text="{Binding Path=OrgName}" VerticalAlignment="Center" /> 
                                </StackPanel> 
                            </telerikCore:HierarchicalDataTemplate> 
</Grid.Resources> 
 

Notes:  There may be a better way to do this but this is what I came up with and it serves my purpose.


0
Heather
Top achievements
Rank 1
answered on 23 Sep 2009, 01:07 PM
Yep - know how to use the template and selector.  In your example you won't get two parent nodes though will you?  Isn't it like:
Organization Name
    Peep Node
    Peep Node
    Equip Node
    Equip Node

I'm trying to get
Organization Name
    Peeps
        Peep Node
        Peep Node
    Equip
        Equip Node
        Equip Node

Guess I can create an object that "houses" the respective collection but was trying to do it without throwing more containing objects into the viewmodel.  Ex:  Organization has collection of ChildHolder, PeepChildHolder exposes Peeps collection, EquipChildHolder exposes Equip collection.
0
Dave
Top achievements
Rank 1
answered on 23 Sep 2009, 01:34 PM
Yea that sounds like you need another level.  I did not need the "peeps" and "equip" aggregation.  In my situation I wanted all the "peeps" and all the "equips" at the same level.
 
0
Heather
Top achievements
Rank 1
answered on 23 Sep 2009, 01:35 PM
Thanks for your quick responses.
Tags
TreeView
Asked by
Dave
Top achievements
Rank 1
Answers by
Dave
Top achievements
Rank 1
Heather
Top achievements
Rank 1
Share this question
or