Silverlight is an application framework that allows us to create apps that provide rich interaction in a web environment. One of the most important concepts in this technology that one must clearly understand is databinding. It is a pretty useful concept to display and work with data. It ties the user- interface to model.
This article aims to fully explain the following concepts and topics:
- composition of the Binding
- creation of a Binding
- importance of INotifyPropertyChanged interface
- fallback and null values for troublesome bindings
DataBinding can be exploited to a great extent when the direction of the data flow is established and the controls are designed in a way to perform change notifications. It is purely comprised of a Binding Expression and a Data Context.
To bind a datasouurce, you need the following information:
- Source object – can be the UI element
- Target – can be a data template
- Mode – can be one way, two way or one time
Let’s look at the composition of a Binding. The binding expression is specified in the XAML markup with the following format:
<TextBox x:Name="TextBoxAge" Text="{Binding Path=Age}" />
In the above example, the textbox is using the Path variable to bind to a property by name “Age”. The property “Age” is expected to be part of the other important part of DataBinding – the DataContext. DataContext is a property on the TextBox and many other Silverlight controls. In this case, you can set it for the TextBox or its parent. But make sure you set it at the right level of the control heierachy otherwise it can be overridden. The following code shows you how to set a DataContext on a user control object.
private void UserControl_Loaded(object sender, RoutedEventArgs e) { newStudent.Age = 10; this.DataContext = newStudent; }
When you execute this code, you will find that the TextBox is bound to the Age property and has a value of 10. The TextBox can also reflect changes made to the DataContext. Silverlight allows this to happen by the way it processes the underlying objects when it looks for data in them. And in particular it looks for objects to see if they have implemented the INotifyPropertyChanged interface. Changes to the underlying model have to reflect, so the model objects needs to implement this interface. The following sample shows that our Student class has implemented the INotifyPropertyChanged interface.
public class Student:INotifyPropertyChanged { int _age; public int Age { get { return _age; } set { if (_age != value) { _age = value; RaisePropertyChanged("Age"); } } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; void RaisePropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } #endregion }
Now, add a button in the mark-up and attached a click event handler, like below.
<Button x:Name="ButtonChangeAge" Click="ButtonChangeAge_Click" Content="Change Age" Height="30" Width="90"></Button> private void ButtonChangeAge_Click(object sender, RoutedEventArgs e) { newStudent.Age = 11; this.DataContext = newStudent; }
On the button click, the value would change to 11.
Let’s look at the second part of the binding expression – the Binding mode. The default mode is one-way. Look at the MSDN article in the references section for more understanding of the different modes. Two-Way Binding enables you propagate changes on both the sides.
The Binding is not limited to primitive types alone. It can be extended to any object. Also noteworthy is that Binding can at times return null or not at all return values. In such cases, TargeNullValue and FallBackValue properties of the Binding come in handy. This is introduced in Silverlight 4.
TargetNullValue should be used if the underlying binding can return null values, and you would like to handle it with a replacement. The following code replaces the null value with 25.
<TextBox x:Name="TextBlockAge" Text="{Binding Path=Age, Mode=TwoWay, TargetNullValue=25}" />
Similarly, FallBackValue handles situations when the underlying binding is unable to return any values. The following code provides a fall back value of 0 in such a case.
<TextBox x:Name="TextBlockAge" Text="{Binding Path=Age, Mode=TwoWay, FallbackValue=0}" />
I hope this information helps you fully understand databinding. Happy reading!