Databinding for nested collections in XAML (WPF and Silverlight)

In Blend, you can drag a collection from the Data pane to the artboard to generate a listbox that is databound to the collection.  You may then drag/drop (in Detail mode) properties under the collection to create textblocks databound to the selected item in the listbox. But if you have nested collections, this is currently not supported (v4).

This post shows sample code for databinding a nested collection:
Assuming there is an AuthorDataSource with this structure:

Authors (list)
 - - Name
 - - Books (list)
     | -  - Title
     | -  - Contents

Sample code :
  <Window.Resources>
    <DataTemplate x:Key="ItemTemplate1">
      <StackPanel>
        <TextBlock Text="{Binding Name}"/>
      </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="ItemTemplate2">
      <StackPanel>
        <TextBlock Text="{Binding Title}"/>
      </StackPanel>
    </DataTemplate>
  </Window.Resources>
  <Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource AuthorDataSource}}">
    <ListBox x:Name="AuthorList" ItemTemplate="{DynamicResource ItemTemplate1}" ItemsSource="{Binding Authors }" >
    <ListBox x:Name="BookList" DataContext="{Binding SelectedItem, ElementName=AuthorList}" ItemsSource="{Binding Books }" ItemTemplate="{DynamicResource ItemTemplate2}" />
    <TextBlock  x:Name="BookContent"   DataContext="{Binding SelectedItem, ElementName=BookList}"  Text="{Binding Contents }" />
  </Grid>

The result would be 2 listboxes and a textblock.  The AuthorList listbox would list names of authors.  Selecting an author in AuthorList would list all books written by that author in the BookList listbox.  Selecting a title in Booklist would display the contents of the book in the textbock.
 

Same codes in listbox BookList are applicable to N levels of nested collections

Comments

  • Anonymous
    October 17, 2010
    What if BookContent was outside the Grid? How would you bind to the BookList?

  • Anonymous
    February 01, 2011
    Hi Rafael, sorry I didn't get what you mean "outside the grid"? You mean the LayoutRoot? All elements are in the same root if they are in the same page or window. For elements in different page/window, you may use DataStore to pass the data, see my other blog post described how to do that. blogs.msdn.com/.../databind-selected-items-across-different-pages.aspx