user113164
user113164

Reputation: 1507

How to use the wpf treeview with nested objects of different types

I have two classes that I'd like to show in a treeview.

In my main window, I have an observable collection of a certain type of object, call it object a. Object a contains an observable collection of another type of object, object b. Each object b contains an observable collection of object b's.

For example, I might have something that looks like this

ListOfObjectA's

-ObjectA1

--ListOfObjectB's

---ObjectB

----ListOfObjectB's

-----ObjectB

-ObjectA2

--ListOfObjectB's

---ObjectB

What should my xaml look like to bind the treeview to something like that?

Sorry if I'm not explaining this well, I'm new to wpf.

Upvotes: 3

Views: 6932

Answers (2)

Andy
Andy

Reputation: 30418

RB has the right idea. This is where WPF's ability to apply templates to normal .NET objects becomes very powerful.

You need to specify two HierarchicalDataTemplates, one for objects of type a, and the other for objects of type b. Something like this :

<TreeView>
    <TreeView.Resources>
        <HierarchicalDataTemplate TargetType="{x:Type local:a}">
            <!-- XAML to display objects of type a -->
        </HierarchialDataTemplate>
        <HierarchicalDataTemplate TargetType="{x:Type local:b}">
            <!-- XAML to display objects of type b -->
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

You will need to specify bindings for the ItemsSource property of each template so that WPF knows where to get child objects from. Also, you'll need to add an xmlns declaration to the root node specifying the namespace that the objects live in (represented by local in the sample code above).

Upvotes: 8

RB Davidson
RB Davidson

Reputation: 628

I know enough WPF to be really dangerous, but I'm pretty sure the HierarchicalDataTemplate is the solution to your problem. My XAML skill are iffy, so I am can't write good example code for you. Here is how I used the HierarchicalDataTemplate in my project. I hope this gives you some good ideas.

<TreeView Grid.Row="1" 
          Grid.Column="1" 
          ItemsSource="{Binding Children}" 
          SelectedItemChanged="TreeView_SelectedItemChanged" 
          ContextMenu="{StaticResource MenuContextMenu}">

  <TreeView.ItemTemplate>
    <HierarchicalDataTemplate  ItemsSource="{Binding Children}" >
      <!--<TextBlock Text="{Binding Path=ItemName}" Margin="5,0,5,0" />-->
      <Grid  ContextMenu="{StaticResource ContextMenu}"   >
        <TextBlock  Name="ShownItem" 
                          Text="{Binding Path=ItemName}" 
                          Margin="0,0,0,0" />

          <TextBox Name="EditBox" 
                 Text="{Binding Path=ItemName}" 
                 Visibility="{Binding Path=Visibility}"
                 Style="{StaticResource EditableTextBox}" 
                 IsVisibleChanged="EditBox_IsVisibleChanged"
                 PreviewKeyDown="EditBox_KeyDown"
                 Margin="0,2,0,2"
                   >

              </TextBox>

      </Grid>
     </HierarchicalDataTemplate>
  </TreeView.ItemTemplate>
</TreeView>

Upvotes: 1

Related Questions