Master-detail scenario
In the simplest master-detail scenario, clicking a particular item of an ItemsControl causes the details about that item to be displayed in another control. For example, an application may display a list of customer names in a ListBox, and clicking a particular customer causes TextBlocks to be updated with the address, phone number and date of birth of that customer.
In this post I will use a data source with the planets of the solar system: clicking on the name of a planet in the ListBox causes its picture and information to be displayed in a templated ContentControl. The ListBox plays the role of the master and the ContentControl presents the detail.
In the resources section of the Window, I have an XmlDataProvider with the planet data and a CollectionViewSource with the Source property bound to the provider (for more information about CollectionViewSource see my previous post). Here is the markup for the ListBox bound to the CollectionViewSource:
<!- master ->
<ListBox ItemsSource="{Binding Source={StaticResource cvs}}" DisplayMemberPath="@Name" Padding="5" Margin="0,0,5,0"/>
I also need a ContentControl, which is used to display the details of the selected item. The markup below may seem a little strange at first: we are binding a ContentControl (which displays a single item) to a collection of items? (Notice that its Content’s Binding is the same as the Binding in the ListBox’s ItemsSource.) This markup works fine because the data binding engine is smart enough to distinguish between the two targets. When binding an ItemsControl to a collection we get the collection; when binding a ContentControl to a collection we get the current item of that collection. This is what makes the master-detail scenario so simple in WPF.
<!- detail ->
<ContentControl ContentTemplate="{StaticResource detailTemplate}" Content="{Binding Source={StaticResource cvs}}"/>
To specify how the details of the planet data should be displayed in the ContentControl, we use a DataTemplate. The following markup shows the data-binding specific parts of the DataTemplate. Notice that because I am binding to XML, the Binding is using XPath instead of Path.
<DataTemplate x:Key="detailTemplate">
(…)
<Image Source="{Binding XPath=Image, Converter={StaticResource stringToImageSource}}" />
(…)
<StackPanel Orientation="Horizontal" Margin="5,5,5,0">
<TextBlock Text="Orbit: " FontWeight="Bold" />
<TextBlock Text="{Binding XPath=Orbit}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5,0,5,0">
<TextBlock Text="Diameter: " FontWeight="Bold"/>
<TextBlock Text="{Binding XPath=Diameter}" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5,0,5,5">
<TextBlock Text="Mass: " FontWeight="Bold"/>
<TextBlock Text="{Binding XPath=Mass}" />
</StackPanel>
(…)
</DataTemplate>
Here is a screen shot of the completed sample:
Here you can find the VS project with this sample code. This works with September CTP WPF bits.
Anonymous
This sample doesn’t work in Jan CTP - details are always emty.
Why?
November 19, 2005 at 2:02 pm
Bea
Unfortunately there was a bug in this particular scenario that was introduced after September CTP bits. Please look for a fix in a future release and thanks for the feedback.
November 20, 2005 at 11:11 am
Anonymous
Oh, thank you very much for your responce.
I would greatly appreciate it if you could create a sample illustrating the use of GridView and GridViewRowPresenter in one of your future posts.
Thank you.
November 21, 2005 at 12:19 pm
Bea
Alright, I will make a blog post on GridView and GridViewRowPresenter. It won’t be the next one, but the one after that.
November 22, 2005 at 11:53 am
Anonymous
Thank you very much.
November 23, 2005 at 3:24 pm
Bea
I added a sample with GridView and GridViewRowPresenter: How do I implement a data bound ListView?. Let me know if you have any other questions on this.
February 25, 2006 at 6:28 pm
Ankit Gothi
can you pls tell ..how to open a new user control or window and bind it with the details of the planet selected from the list box.
pls answer it as soon as possible
It would be great help.
Thnx in advance.
September 4, 2009 at 2:17 am
Bea
Hi Ankit,
You will have to set the DataContext of the user control or window to the ListBox’s SelectedItem property (or the view’s CurrentItem).
Thanks,
Bea
October 11, 2009 at 7:20 pm