It is a very common scenario to bind to a collection and display data in a master/details view. In this walkthrough you create a collection of Book objects, display them in a list by using a data template. You also create a details view that updates when the selection in the master list changes.
This walkthrough illustrates the following tasks:
Creating a collection of business objects.
Creating the user interface for the master list.
Setting the data source for the master list.
Creating the details view.
Setting the data context for the detail view.
You need the following components to complete this walkthrough:
All of the Silverlight software is available from the Silverlight download site.
Creating a Silverlight Project
The first step is to create a Silverlight project.
To create a Silverlight project
Next, you create a collection of Book objects.
To create a collection of Book objects
Add a class named Book to the project.
Add the following code to the Book class.
The following code contains a Book class that represents the business object to display in a ListBox control.
Public Sub New(ByVal isbn As String, ByVal title As String, _
ByVal publishdate As DateTime, ByVal price As Double)
Me.ISBN = isbn
Me.Title = title
Me.PublishDate = publishdate
Me.Price = price
End Sub
'Define the public properties
Private isbnValue As String
Public Property ISBN() As String
Get
Return isbnValue
End Get
Set(ByVal value As String)
isbnValue = value
End Set
End Property
Private titleValue As String
Public Property Title() As String
Get
Return titleValue
End Get
Set(ByVal value As String)
titleValue = value
End Set
End Property
Private publishDateValue As DateTime
Public Property PublishDate() As DateTime
Get
Return publishDateValue
End Get
Set(ByVal value As DateTime)
publishDateValue = value
End Set
End Property
Private priceValue As Double
Public Property Price() As Double
Get
Return priceValue
End Get
Set(ByVal value As Double)
priceValue = value
End Set
End Property
public Book() { }
public Book(string isbn, string title,
DateTime publishdate, double price)
{
this.ISBN = isbn;
this.Title = title;
this.PublishDate = publishdate;
this.Price = price;
}
//Define the public properties
public string ISBN { get; set; }
public string Title { get; set; }
public DateTime PublishDate { get; set; }
public double Price { get; set; }
Open MainPage.xaml.vb or MainPage.xaml.cs.
Add the following Imports or using statement to the top of the file.
Imports System.Collections.ObjectModel
using System.Collections.ObjectModel;
After the Page class constructor, add the following read-only generic property named AllBooks.
The following code creates a generic ObservableCollection<(Of <(T>)>) property that contains the Book type. If the collection is null, the get method creates the collection and adds one book. The ObservableCollection<(Of <(T>)>) type raises list-changed events when an object is added or removed from the collection.
' Create a collection to store data items.
Private _AllBooks As ObservableCollection(Of Book)
Public ReadOnly Property AllBooks() As ObservableCollection(Of Book)
Get
If (_AllBooks Is Nothing) Then
_AllBooks = New ObservableCollection(Of Book)
_AllBooks.Add(New Book("3390092284", "All About Dogs", _
New DateTime(2004, 3, 4), 12.99))
End If
Return _AllBooks
End Get
End Property
private ObservableCollection<BookStore.Book> _AllBooks;
public ObservableCollection<Book> AllBooks
{
get
{
if (_AllBooks == null)
{
_AllBooks = new ObservableCollection<Book>();
_AllBooks.Add(new Book("3390092284", "All About Dogs",
new DateTime(2004, 3, 4), 12.99));
}
return _AllBooks;
}
}
Creating the User Interface for the Master List
Next you create the user interface for the master list by using a data template and set up the binding targets.
To create the user interface for the master list
Open MainPage.xaml.
In XAML view, add the following XAML, replacing the <Grid> tags.
This XAML adds a StackPanel for layout purposes and a ListBox named MyBooks to contain the list of books. It also uses a DataTemplate to define how the books should display in the ListBox. It displays the list of books as ISBN numbers and book titles in two TextBlock controls. The StackPanel has a horizontal orientation, which will put the two TextBlock controls side by side.
To set up a binding you must set the ItemsSource for the ListBox, which provides its content for the list box items. In XAML, the ItemsSource is set to be a Binding by using a markup extension. For more information, see Binding Markup Extension. The Text properties on the TextBlock elements inside the data template are bound properties. In addition to declaring the property as bound, each TextBlock includes the path to the property on the data object it will be bound to. In this case, the TextBlock controls are bound to IBSN and Title.
<StackPanel>
<ListBox x:Name="MyBooks" Margin="5" ItemsSource="{Binding Mode=OneWay}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding ISBN}" Margin="0,0,50,0" />
<TextBlock Text="{Binding Title}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
...
</StackPanel>
Setting the Data Source for the Master List
Next, you define the data source for the master list by setting the DataContext property for the ListBox.
To set the data source for the master list
Open MainPage.xaml.vb or MainPage.xaml.cs.
Add the following code to the Page constructor, after the call to InitializeComponent.
The following code adds two items to the collection and then sets the data context for the list box. All the children of the list box will have the same data context, unless another data context is set further down the object tree or is overridden using the Source property.
' You can add items to your collection.
AllBooks.Add(New Book("4458907683", "Training Your Dog", _
New DateTime(2000, 2, 8), 44.25))
AllBooks.Add(New Book("0446675385", "Good Owners, Great Dogs", _
New DateTime(1999, 9, 1), 15.99))
'Set the data context for the list of books
MyBooks.DataContext = AllBooks
//You can add items to your collection
AllBooks.Add(new Book("4458907683", "Training Your Dog",
new DateTime(2000, 2, 8), 44.25));
AllBooks.Add(new Book("0446675385", "Good Owners, Great Dogs",
new DateTime(1999, 9, 1), 15.99));
//Set the data context for the list of books
MyBooks.DataContext = AllBooks;
Build and run the application.
When the application is running, you will see a ListBox displaying three books in the collection.
Creating the Details View
One of the most common scenarios when displaying data is a master/details or parent/child scenario. This means that selecting an item in a master list causes detail display to update with the corresponding child data.
This section shows how to select an item in the master list and display its details. First, you will create the additional UI to contain the list item details.
To create the details view
Open MainPage.xaml.
After the closing </ListBox> tag, but before the closing </StackPanel> tag, add the following XAML in the main stack panel.
The following XAML adds a StackPanel which contains a rectangle and a stack panel named BookDetails. The rectangle serves as a dividing line between the master and the details data. The BookDetails stack panel contains four TextBlock controls to display the book title, ISBN, published date, and price. Each text block has a binding that associates its text property with the book property it should display.
<StackPanel>
<!--Visual division between the list and the details-->
<Rectangle HorizontalAlignment="Left" Width="400" Height="2"
Fill="Red" Margin="0,10,0,10"/>
<!--The UI for the details view-->
<StackPanel x:Name="BookDetails">
<TextBlock Text="{Binding ISBN, Mode=OneWay}" />
<TextBlock Text="{Binding Title, Mode=OneWay}" />
<TextBlock Text="{Binding PublishDate, Mode=OneWay }" />
<TextBlock Text="{Binding Price, Mode=OneWay}" />
</StackPanel>
</StackPanel>
Setting the Data Context for the Detail View
You have created bindings to associate the details text block controls with the data they should display, but you must also set the data context so these bindings will function correctly. You do this by handling the SelectionChanged event for the MyBooks list box, and setting its data context to the currently selected item.
To set the data context for the detail view
Open MainPage.xaml.vb or MainPage.xaml.cs.
Add the following code to the end of the Page constructor.
This code associates the SelectionChanged event with its handler and sets the selected item to the first item in the list. You can also associate an event with its handler in XAML.
AddHandler MyBooks.SelectionChanged, AddressOf Me.MyBooks_SelectionChanged
MyBooks.SelectedIndex = 0
this.MyBooks.SelectionChanged +=
new SelectionChangedEventHandler(MyBooks_SelectionChanged);
MyBooks.SelectedIndex = 0;
Add the following event handler to the Page class.
This code sets the data context for the BookDetails stack panel to the currently selected item of the MyBooks list box.
Private Sub MyBooks_SelectionChanged(ByVal sender As Object, _
ByVal e As SelectionChangedEventArgs)
Dim myBooks As ListBox = CType(sender, ListBox)
BookDetails.DataContext = myBooks.SelectedItem
End Sub
private void MyBooks_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox myBooks = sender as ListBox;
BookDetails.DataContext = myBooks.SelectedItem;
}
Build and run the application.
When the application is running, you will see a ListBox displaying three books in the collection. In addition, you see the details for the first book displayed underneath the red line on the page. If you select one of the other items in the master list, its details will display.
In addition to the steps covered in this walkthrough, you could also implement a customer type converter to display the publish date and book price in more readable format. For more instruction on how to do this, see the "Data Conversions" section of Data Binding.
Reference
Concepts