How to: Bind to a Collection and Display Information Based on Selection
In a simple master-detail scenario, you have a data-bound ItemsControl such as a ListBox. Based on user selection, you display more information about the selected item. This example shows how to implement this scenario.
Example
In this example, People
is an ObservableCollection of Person
classes. This Person
class contains three properties: FirstName
, LastName
, and HomeTown
, all of type string.
<Window x:Class="SDKSample.Window1"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SDKSample"
Title="Binding to a Collection"
SizeToContent="WidthAndHeight">
<Window.Resources>
<ObjectDataProvider x:Key="MyFriends" ObjectType="{x:Type local:People}" />
...
</Window.Resources>
<StackPanel>
<TextBlock FontFamily="Verdana" FontSize="11"
Margin="5,15,0,10" FontWeight="Bold">My Friends:</TextBlock>
<ListBox Width="200" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Source={StaticResource MyFriends}}"/>
<TextBlock FontFamily="Verdana" FontSize="11"
Margin="5,15,0,5" FontWeight="Bold">Information:</TextBlock>
<ContentControl Content="{Binding Source={StaticResource MyFriends}}"
ContentTemplate="{StaticResource DetailTemplate}"/>
</StackPanel>
</Window>
The ContentControl uses the following DataTemplate that defines how the information of a Person
is presented:
<DataTemplate x:Key="DetailTemplate">
<Border Width="300" Height="100" Margin="20"
BorderBrush="Aqua" BorderThickness="1" Padding="8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="First Name:"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=FirstName}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Last Name:"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=LastName}"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="Home Town:"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=HomeTown}"/>
</Grid>
</Border>
</DataTemplate>
The following is a screenshot of what the example produces. The ContentControl shows the other properties of the person selected.
The two things to notice in this example are:
The ListBox and the ContentControl bind to the same source. The Path properties of both bindings are not specified because both controls are binding to the entire collection object.
You must set the IsSynchronizedWithCurrentItem property to true for this to work. Setting this property ensures that the selected item is always set as the CurrentItem. Alternatively, if the ListBox gets it data from a CollectionViewSource, it synchronizes selection and currency automatically.
Note that the Person
class overrides the ToString method the following way. By default, the ListBox calls ToString and displays a string representation of each object in the bound collection. That is why each Person
appears as a first name in the ListBox.
public override string ToString()
{
return firstname.ToString();
}
Public Overrides Function ToString() As String
Return Me._firstname.ToString
End Function
For the complete sample, see Binding to a Collection Sample.
See Also
Tasks
How to: Use the Master-Detail Pattern with Hierarchical Data
How to: Use the Master-Detail Pattern with Hierarchical XML Data
Concepts
Data Binding Overview
Data Templating Overview