Written by:
Microsoft
Microsoft
Data Binding to Controls
Mar 05, 2009
Login to Rate
:( Error
0
0
Summary
Describes how to data bind to a control and customize the display.
Most Silverlight-based applications display data in controls. In many cases, the data is a business object or
a collection of business objects, such as stock quotes, headlines, or images. In addition, you often want to
enable the user to select an item from a list and then display details about that item in another control, such as
a text box. This QuickStart shows you how to bind a control to a single item or bind a list control to a
collection of items. In addition, this QuickStart shows you how to customize the display of control items,
implement a details view based on a selection, and convert data for display.
This QuickStart contains the following sections:
For a complete description of binding, see Data Binding in the Silverlight documentation on MSDN.
For more information about the controls available with Silverlight, see Controls in the Silverlight documentation on MSDN.
Binding a Control to a Single Item
A data binding consists of a target and a source. The target of a binding typically is a control property. The target must be a DependencyProperty.
The following shows an example of binding a control to a single item. The target is the Text property of a text box control. The source is a simple music Recording class.
XAML
<Grid x:Name="LayoutRoot" Background="White" HorizontalAlignment="Center" >
<TextBox VerticalAlignment="Top" IsReadOnly="True" Margin="5"
TextWrapping="Wrap" Height="50" Width="200"
Text="{Binding Mode=OneWay}" x:Name="textBox1"/>
</Grid>
C#
// A simple business object
public class Recording
{
public Recording() { }
public Recording(string artistName, string cdName, DateTime release)
{
Artist = artistName;
Name = cdName;
ReleaseDate = release;
}
public string Artist { get; set; }
public string Name { get; set; }
public DateTime ReleaseDate { get; set; }
// Override the ToString method.
public override string ToString()
{
return Name + " by " + Artist + ", Released: " + ReleaseDate.ToShortDateString();
}
}
...
// Set the data context to a new Recording.
textBox1.DataContext = new Recording("Chris Sells", "Chris Sells Live",
new DateTime(2008, 2, 5));
Visual Basic
Public Class Recording
Public Sub New()
End Sub
Public Sub New(ByVal artistName As String, ByVal cdName As String, _
ByVal release As DateTime)
Artist = artistName
Name = cdName
ReleaseDate = release
End Sub
Private artistValue As String
Private nameValue As String
Private releaseDateValue As DateTime
Public Property Artist() As String
Get
Return artistValue
End Get
Set(ByVal value As String)
artistValue = value
End Set
End Property
Public Property Name() As String
Get
Return nameValue
End Get
Set(ByVal value As String)
nameValue = value
End Set
End Property
Public Property ReleaseDate() As DateTime
Get
Return releaseDateValue
End Get
Set(ByVal value As DateTime)
releaseDateValue = value
End Set
End Property
' Override ToString.
Public Overloads Overrides Function ToString() As String
Return Name + " by " + Artist + ", Released: " + releaseDate.ToShortDateString()
End Function
End Class
...
' Set the data context to a new recording.
textBox1.DataContext = New Recording("Chris Sells", "Chris Sells Live", _
New DateTime(2008, 2, 5))
To display a music recording in a text box, the control's Text property is set to a Binding by using a markup extension. In this example, the mode is set to BindingMode.OneWay, which specifies that data is retrieved from the source, but changes are not propagated back to the source. For more information about markup extensions and the syntax, see Binding Markup Extension in the Silverlight documentation on MSDN.
The Recording class has three public properties and a ToString method override. The properties are Artist, Name, and ReleaseDate. The ToString method is significant, because if no formatting is specified, the ToString method is called on a bound object for display purposes. The Binding.Source property for the binding is not set directly; instead, the FrameworkElement.DataContext property for the TextBox control is set to a new Recording object.
Binding a Control to a Collection of Objects
The previous example demonstrates the syntax you use to bind data to controls, but it is not very realistic.
A more common scenario is to bind to a collection of business objects. The generic ObservableCollection
class is a good collection choice for data binding, because it implements the INotifyPropertyChanged and INotifyCollectionChanged interfaces. These interfaces provide change notification to bound controls when an item in the list changes or a property of the list itself changes. If you want your bound controls to update with changes to properties of objects in the collection,
the business object should also implement INotifyPropertyChanged.
The following example binds a collection of music Recording objects to a ComboBox.
To try this example, click the down arrow in the combo box to see the list of bound recordings.
XAML
<StackPanel x:Name="LayoutRoot" Background="White">
<ComboBox x:Name="ComboBox1" Margin="5" Height="40" Width="300"
ItemsSource="{Binding Mode=OneWay}" />
</StackPanel>
C#
public ObservableCollection<Recording> MyMusic = new ObservableCollection<Recording>();
public Page()
{
InitializeComponent();
// Add items to the collection.
MyMusic.Add(new Recording("Chris Sells", "Chris Sells Live",
new DateTime(2008, 2, 5)));
MyMusic.Add(new Recording("Luka Abrus",
"The Road to Redmond", new DateTime(2007, 4, 3)));
MyMusic.Add(new Recording("Jim Hance",
"The Best of Jim Hance", new DateTime(2007, 2, 6)));
// Set the data context for the combo box.
ComboBox1.DataContext = MyMusic;
}
Visual Basic
Public MyMusic As New ObservableCollection(Of Recording)()
Public Sub New()
InitializeComponent()
' Add items to the collection.
MyMusic.Add(New Recording("Chris Sells", "Chris Sells Live", _
New DateTime(2008, 2, 5)))
MyMusic.Add(New Recording("Luka Abrus", "The Road to Redmond", _
New DateTime(2007, 4, 3)))
MyMusic.Add(New Recording("Jim Hance", "The Best of Jim Hance", _
New DateTime(2007, 2, 6)))
' Set the data context for the combo box.
ComboWithTemplate.DataContext = MyMusic
End Sub
To display the music recordings in the ComboBox, the control's ItemsControl.ItemsSource property is set to a Binding, and the FrameworkElement.DataContext property for the ComboBox control is set to the collection of Recording objects, which provides the source for the binding. A ComboBoxItem is created for each item in the collection. ToString is automatically called on each Recording object to display it in the combo box item.
Displaying Items in a Control by using a Data Template
You can display items in a list by using the item's ToString method. However, a more common scenario
is to provide a customized display of data bound items by using a DataTemplate.
A DataTemplate enables you to customize how list items are displayed in a control. Typically, you set the data template
by using the ContentControl.ContentTemplate property of a content control or the ItemsControl.ItemTemplate property of an items control.
The following example shows the same list of recordings bound to a combo box by using a data template. A combo
box is an ItemsControl, which means that you establish a data template for each item
by setting its ItemTemplate property to a data template. To try this
example, click the down arrow to see the list of recordings. Notice how the recordings look different from
the previous example. The artist and CD name are displayed in a custom format.
XAML
<ComboBox x:Name="ComboWithTemplate" Margin="5"
Width="400" HorizontalAlignment="Left"
ItemsSource="{Binding Mode=OneWay}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="2">
<TextBlock Text="Artist:" Margin="2" />
<TextBlock Text="{Binding Artist}" Margin="2" />
<TextBlock Text="CD Name:" Margin="10,2,0,2" />
<TextBlock Text="{Binding Name}" Margin="2" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
In the XAML, you can see the data template definition. The data template contains a StackPanel with four TextBlock controls. The stack panel has a horizontal orientation so that the four text block controls appear side by side. Two of the TextBlock controls are bound to the Artist and Name properties of a Recording object. The other two TextBlock controls display static text. For each bound item, the binding provides the path to the property on the Recording object. As in the previous example, this binding relies on the data context to be set to the list of recordings.
This XAML uses the property element syntax. For more information about XAML syntax, see XAML Overview in the Silverlight documentation on MSDN. For more information about control layout, see Object Positioning and Layout in the Silverlight documentation on MSDN.
Adding a Details View
To display the details of an item when it is selected from a collection, you have to create the appropriate
UI and bind the UI to the data that you want it to display. To do this, you set the data context for the
bindings to an item in the collection, instead of setting it to the entire collection. In addition, you must update the data
context as the selected item changes.
The following example shows the same list of recordings bound to a combo
box by using a data template. However, this example also includes a details view. To try this example, click the down arrow and select different recordings. Notice that the artist, CD name, and release date appear in a details view below the combo box.
XAML
<!--The UI for the details view-->
<StackPanel x:Name="RecordingDetails">
<TextBlock FontWeight="Bold" Text="{Binding Artist, Mode=OneWay}" Margin="5,0,0,0"/>
<TextBlock FontStyle="Italic" Text="{Binding Name, Mode=OneWay}" Margin="5,0,0,0"/>
<TextBlock Text="{Binding ReleaseDate, Mode=OneWay}" Margin="5,0,0,0" />
</StackPanel>
C#
ComboWithTemplate.SelectionChanged +=
new SelectionChangedEventHandler(ComboWithTemplate_SelectionChanged);
ComboWithTemplate.SelectedIndex = 0;
...
void ComboWithTemplate_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox myCDs = sender as ComboBox;
RecordingDetails.DataContext = MyMusic[myCDs.SelectedIndex];
}
Visual Basic
AddHandler ComboWithTemplate.SelectionChanged, _
AddressOf ComboWithTemplate_SelectionChanged
ComboWithTemplate.SelectedIndex = 0
...
Private Sub ComboWithTemplate_SelectionChanged(ByVal sender As Object, _
ByVal e As SelectionChangedEventArgs)
Dim myCDs As ComboBox = TryCast(sender, ComboBox)
RecordingDetails.DataContext = MyMusic(myCDs.SelectedIndex)
End Sub
In this example, a StackPanel is added to the user control that contains the existing combo box.
A Rectangle serves as a dividing line under the ComboBox.
Next is a stack panel that contains four text blocks to display the recording details.
The TextBlock.Text property of each text block is bound to a property on the Recording
object. To update the details view, the ListBox.SelectionChanged event for the list
box is handled, and in the event handler, the FrameworkElement.DataContext is set to the
selected item. To make sure that an item is always selected, the selected item is set to the first item in the
list box when the page is initialized. When you try the example, the text box portion of the combo box is
populated with the selected item.
Converting Data for Display in Controls
If you want to format and display a non-string type in a control, such as a TextBox,
you can use a converter. For example, you could display a date in a custom format instead of the default
date-time format.
The following example shows a converter implementation for the release date in the list of
recordings.
To try this example, click the down arrow and select different recordings. Notice that the release date
in the drop-down list and details view is displayed in a custom format.
XAML
<UserControl x:Class="DataBindingControlsQuickStart4.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataBindingControlsQuickStart4"
Width="300" Height="200">
<UserControl.Resources>
<local:StringFormatter x:Key="StringConverter"/>
<UserControl.Resources />
<!--The UI for the details view-->
<StackPanel x:Name="RecordingDetails">
<TextBlock Text="{Binding Artist, Mode=OneWay}" />
<TextBlock Text="{Binding Name, Mode=OneWay}" />
<TextBlock Text="{Binding ReleaseDate,
Mode=OneWay, Converter={StaticResource StringConverter},
ConverterParameter=Released: \{0:d\}}" />
</StackPanel>
C#
public class StringFormatter : IValueConverter
{
// This converts the value object to the string to display.
// This will work with most simple types.
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
// Retrieve the format string and use it to format the value.
string formatString = parameter as string;
if (!string.IsNullOrEmpty(formatString))
{
return string.Format(culture, formatString, value);
}
// If the format string is null or empty, simply
// call ToString() on the value.
return value.ToString();
}
// No need to implement converting back on a one-way binding
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Visual Basic
Public Class StringFormatter
Implements IValueConverter
' This converts the DateTime object to the string to display.
Public Function Convert(ByVal value As Object, ByVal targetType As Type, _
ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) _
As Object Implements IValueConverter.Convert
' Retrieve the format string and use it to format the value.
Dim formatString As String = TryCast(parameter, String)
If Not String.IsNullOrEmpty(formatString) Then
Return String.Format(culture, formatString, value)
End If
' If the format string is null or empty, simply call ToString()
' on the value.
Return value.ToString()
End Function
' No need to implement converting back on a one-way binding
Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, _
ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) _
As Object Implements IValueConverter.ConvertBack
Throw New NotImplementedException()
End Function
End Class
A converter is a class that derives from the IValueConverter interface. IValueConverter has two methods; Convert and ConvertBack. For a one-way binding from the data source
to the binding target, you only have to implement the Convert method. The converter in this example is fairly generic. You can pass the desired string format as a parameter, and the converter uses the Format method to perform the conversion. If no format string is passed, the converter returns the result of calling
ToString on the object.
Once you implement the converter, you create an instance of the converter class and tell the bindings to use this instance. In this example, this is performed in XAML. An instance of the converter is created as a static resource and assigned a key. The key is used when the converter property is set on the binding.
For more information about how to convert data for display in controls, see IValueConverter in the Silverlight documentation on MSDN.
See Also
Send Feedback