Skip to main content

Microsoft Silverlight

MicrosoftWritten by:
Microsoft
Microsoft

Data Binding to Controls

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

Leave a Comment Comments (5) RSS Feed


tmorton

Member

Contributor

2225 Points

#1 July 23, 2009 4:56 AM

Thanks for the tutorial!


tmorton

Member

Contributor

2225 Points

#2 July 23, 2009 4:58 AM

Thanks for the tutorial!


JayNeu

Member

Participant

996 Points

#3 July 23, 2009 5:03 AM

hello world!!!


Kero5hin

Member

Member

37 Points

#4 September 16, 2009 2:29 PM

More More, I want More! Good tutorial.


sarav...

Member

Member

3 Points

#5 September 21, 2009 9:59 AM

Have a look at this link:-) http://tuesdate.com/Journal/View/164

This is much more simpler.

  • 1

You must be logged in to leave a comment. Click here to log in.

Quickstarts

Microsoft Communities