3

How can we bind an object List to a control with its main items and sub items. If the class structure is like this

public class BookChapter
{
 public string Name { get; set; }
 public List<BookPage> Pages {get; set; }
 public List<String> Questions { get; set; }

}
public class BookPage
{
    public string Id { get; set; }
    public string Name { get; set; }
    public List<String> Excercises { get; set; }
}

How can i bind it on a WPF control with ChapterName and Pages associated with every chapters in a single control.

Sebastian
  • 4,625
  • 17
  • 76
  • 145

1 Answers1

3

There are a few ways to achieve this in WPF, one way would involve the use of DataTemplates to describe how you would like your objects to be displayed. Using ItemsControl or derived controls to hold display your collections:

I often separate my styles into various types to make them slightly easier to read e.g:

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication2"
    Title="MainWindow" Height="350" Width="525"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>

    <!-- Book Chapters -->
    <DataTemplate DataType="{x:Type local:BookChapter}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Path=Name}" />
            <ItemsControl ItemsSource="{Binding Path=Pages}" />
        </StackPanel>
    </DataTemplate>

    <!-- Book Pages -->
    <DataTemplate DataType="{x:Type local:BookPage}">
        <StackPanel Orientation="Horizontal" >
            <TextBlock Text="{Binding Path=Id}" Margin="5 0"/>
            <TextBlock Text="{Binding Path=Name}" Margin="5 0"/>
            <ItemsControl ItemsSource="{Binding Path=Exercises}" />
        </StackPanel>
    </DataTemplate>

</Window.Resources>
<Grid>
    <ListBox ItemsSource="{Binding Path=Chapters}" />
</Grid>

Which will produce something that looks like this (based on what I populated your objects with):enter image description here

Without templating your objects, WPF will simply display the collections as ApplicationName.ClassName - the result of ToString, templates give you the ability to define how you would like your classes to be displayed.

You can hold these templates in a separate resource file, and reuse them across your application if required. It's important to note that because I'm templating the actual Type, this template will be used whenever your objects are displayed within this particular Window, unless you specify otherwise.

You can add greater control over when/were these templates are used, by naming them, and only applying them to specific components (http://msdn.microsoft.com/en-us/library/ms742521.aspx).

Chris
  • 8,268
  • 3
  • 33
  • 46
  • How the values Ex1 , Ex2 are displayed on window? For me they are not showing . In Xaml i can't see any controls which is assigned to Excercise property .Will this line alone render all excercise values correctly or we need to design an extra textblock with Binding in xaml to show exercise ? – Sebastian Aug 09 '13 at 08:56
  • Since `Exercise` is just a string collection of `string`, the `ItemsControl` you listed will display the strings as above, the `ItemsControl` will automatically wrap the strings in a `TextBlock`. If you want to add further customisation, you can alter the `ItemContainerStyle`, or alter the `` with a `DataTemplate`. – Chris Aug 09 '13 at 09:35
  • Ah, the problem is the way you're spelling `Exercises`, I corrected the spelling when I was templating it and forgot to point it out. – Chris Aug 09 '13 at 09:45
  • Yes that was the problem...Thanks for pointing out that and now it works – Sebastian Aug 09 '13 at 10:13
  • Good stuff, apologies for the spelling confusion. – Chris Aug 09 '13 at 10:27
  • Can i present the same inside an ItemsControl? My aim is to show it as a list of items inside Stackpanel . Item Control layout is like http://pastebin.com/4jmKnn8v – Sebastian Aug 12 '13 at 08:07
  • That should be fine, this may be relevant: http://stackoverflow.com/questions/3356719/bind-collection-to-stackpanel – Chris Aug 12 '13 at 09:25