Silverlight Tutorials: Data Binding
This article is written by Emil Stoychev (Silverlight MVP).This is the fourth chapter of Silverlight Tutorials for Beginners series.
Data Binding is simple, yet powerful way to connect (bind) your business model and user interface (UI). When the data in your business model changes the UI reflects changes automatically and vice versa (when a user changes the data in the UI the data in the business model is changed).
Binding establishes a connection between two dependant items. Basically, it is an automatic way of transferring information from one item to another.
Content
- Data Context, Dependency Property, Dependency Object
- Types of Binding
- Converters
- Validation in Binding
- Consuming Services
- Sample
Data Context, Dependency Property, Dependency Object
Data Context
In Data Binding we have two objects: target – the UI element and source – the data (business model, entity, etc). While the source property can be a normal .NET property, the target property must be a DependencyProperty. More on that later in the tutorial.
The DataContext is actually the source of data bound to the target. The default source of a binding is the data context. DataContext is inherited to child elements and thus ideal for scenarios where you want to bind multiple elements to a single data source. DataContext is a property of FrameworkElement. Let’s see this in an example:
…
<local:ContactCard x:Name="JohnsBusinessCard"
FullName="John Smith"
Position="Silverlight Developer"
Email="john@smith.com" />
…
<StackPanel DataContext="{StaticResource JohnsBusinessCard}">
<TextBlock Text="{Binding FullName}"
FontWeight="Bold" />
<TextBlock Text="{Binding Position}" />
<TextBlock Text="{Binding Email}" />
</StackPanel>
ContactCard is a custom defined class with three properties – FullName, Position and Email.
All bindings set to the TextBlock elements inside the StackPanel have source the DataContext of the StackPanel – {StaticResource JohnsBusinessCard} in this case.
In case of items control we can think of the DataContext as the particular data item that we bind to at run time. So let’s say we have a list of ContactCard objects set as a DataContext to an ItemsControl. The data context of each of the items in the ItemsControl is the corresponding list element in the list (set as DataContext).
Dependency Property and Dependency Object
DependencyObject and DependencyProperty are fundamental concepts in Silverlight/WPF that provide the base for the underlying property system.
< to be continued… >
Types of Binding
With each binding you can set Mode which defines the direction of the data flow as well as when the binding occurs. There are three available binding modes in Silverlight:
- OneTime – set the target and forget the binding. This mode is useful when you display data and you know that this data will never change or you don’t need to change it. Changes in the source are not propagated to the target.
- OneWay – set the target and update it every time the source changes. This is the default mode. Use it in cases where the user can’t change the target, but you still want to keep the target updated once the source is changed from somewhere (say the code).
- TwoWay – keep both the target and the source updated. Once the source is changed its new value is propagated to the target and vice versa. This is useful in cases where the user can change the target and you want the changes to be written back to the source.
Lets take a look at the syntax:
<TextBlock Text="{Binding Email, Mode=TwoWay}" />
Depending on your case you can select one of the three binding modes. To choose which one is most appropriate for your case you can try to answer yourself the following questions in this order:
- Do I need to update the target when the source change? (yes – OneWay or TwoWay; no – OneTime)
- Do I need to reflect the changes done on the target to the source? (yes – TwoWay; no – OneWay)
< continue with INotifyPropertyChanged… >
Converters
A common scenario in data binding is that you need to format the data displayed to the user. Intuitive examples for that are formatting of DateTime and number values. In Silverlight and WPF this is achieved by applying a ValueConverter (or just Converter) to the data you are binding to.
Converters are classes that derive from the IValueConverter interface. This interface have two methods that should be implemented – Convert and ConvertBack. The Convert method is used when the data flows from the source to the target, while the ConvertBack is used when the data flows in the opposite direction – from the target to the source. In case your binding uses OneTime or OneWay mode you can go only with implementing the Convert method, but that is not considered a good practice as the converters are reusable chunks of code and you never know who and in what situation will use it.
Lets see what a converter look like:
public class DateTimeConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
DateTime dt = (DateTime)value;
return dt.ToString( "dd MMM, yyyy", culture );
}
public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
throw new NotImplementedException();
}
}
Here only the Convert method is implemented. It is important to note that you should always validate the value parameter as it could not be from the type you expect.
// show the xaml syntax – convert as static resource
This is probably the most simplest converter you can ever write. The make it more flexible you can use a ConverterParameter. In different scenarios you may want to format the DateTime value in different way. The specific format can be passed through the ConverterParameter.
<TextBlock Text="{Binding Birthdate, Converter={StaticResource DateTimeConverter}, ConverterParameter=YYYY}" />
Validation in Binding
; content
Consuming Services
; content
Sample
; content