Silverlight is a subset of WPF and it is no surprise that Silverlight's data binding model borrows from WPF. Both technologies use the INotifyPropertyChanged interface and ObservableCollection generic to easily incorporate two way data binding into an application. A CLR object that implements the INotifyPropertyChanged interface and raises a PropertyChanged event whenever a bindable property changes is easily added into the XAML using the binding syntax. Listing 1 shows how to create a class that implements INotifyPropertyChanged and raises the PropertyChanged event. Listing 2 shows how to bind the properties to Text boxes in XAML.
Listing 1: Implementing the INotifyPropertyChanged Interface
1 Imports System.ComponentModel
2
3 Public Class Person
4 Implements INotifyPropertyChanged
5
6 Public Event PropertyChanged(ByVal sender As Object, _
7 ByVal e As System.ComponentModel.PropertyChangedEventArgs) _
8 Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
9
10 Private Sub FirePropertyChanged(ByVal [property] As String)
11 If Not String.IsNullOrEmpty([property]) Then
12 RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs([property]))
13 End If
14 End Sub
15
16 Private _Name As String
17 Public Property Name() As String
18 Get
19 Return _Name
20 End Get
21 Set(ByVal value As String)
22 _Name = value
23 FirePropertyChanged("Name")
24 End Set
25 End Property
26
27 Private _Count As Integer
28 Public Property Count() As Integer
29 Get
30 Return _Count
31 End Get
32 Set(ByVal value As Integer)
33 _Count = value
34 FirePropertyChanged("Count")
35 End Set
36 End Property
37
38 Public Sub New(ByVal name As String, ByVal count As Integer)
39 Me.Name = name
40 Me.Count = count
41 End Sub
42
43 End Class
Listing 2: XAML Data Binding syntax
6 <TextBox Text="{Binding Name, Mode=TwoWay}" />
7 <TextBox Text="{Binding Count, Mode=TwoWay}" />
All that is needed is to set the DataContext of a parent container to an instance of the Person object and that's it, you now have two way data binding. Whenever the underlying object is modified the UI will automatically be updated and whenever the UI is changed the object is updated. Now that's pretty simple.
Now what if we need to bind a collection to a data grid, combo box or even a chart? You could write a custom collection class that implements INotifyPropertyChanged or better yet you can use the ObservableCollection generic class, which already implements the INotifyPropertyChanged. Listing 3 uses the ObservableCollection generic to create a collection of the above Person class.
Listing 3: Using the ObservableCollection Generic
13 Private members As New ObservableCollection(Of Person)
14
15 Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) _
16 Handles Me.Loaded
17 members.Add(New Person("Tony", 5))
18 members.Add(New Person("Sally", 2))
19 members.Add(New Person("John", 8))
20 grid.ItemsSource = members
21 comboBoxName.ItemsSource = members
22 CType(chart.Series(0), DynamicSeriesWithAxes).ItemsSource = members
23 End Sub
The above snippet also includes how to bind the collection to a data grid, chart and combo box. The XAML used to bind this collection to the previously mentioned controls is shown in Listing 4.
Listing 4: Xaml Binding syntax for Datagrid, Chart and ComboBox
17 <data:DataGrid x:Name="grid" Grid.Row="1" Grid.Column="0" AutoGenerateColumns="False" >
18 <data:DataGrid.Columns>
19 <data:DataGridTextColumn Header="Name" FontSize="20" Width="185"
20 Binding="{Binding Mode=TwoWay, Path=Name}" />
21 <data:DataGridTextColumn Header="Count" FontSize="20" Width="188"
22 Binding="{Binding Mode=TwoWay, Path=Count}" />
23 </data:DataGrid.Columns>
24 </data:DataGrid>
38 <charting:Chart x:Name="chart" Grid.Row="2" Grid.Column="0">
39 <charting:Chart.Series>
40 <charting:ColumnSeries
41 DependentValueBinding ="{Binding Mode=TwoWay, Path=Count}"
42 IndependentValueBinding ="{Binding Mode=TwoWay, Path=Name}" />
43 </charting:Chart.Series>
44 </charting:Chart>
49 <ComboBox x:Name="comboBoxName" Width="150" Height="25" HorizontalAlignment="Left" Margin="10,0,0,0">
50 <ComboBox.ItemTemplate>
51 <DataTemplate>
52 <TextBlock Text="{Binding Path=Name}" FontSize="16"/>
53 </DataTemplate>
54 </ComboBox.ItemTemplate>
55 </ComboBox>
With this binding in place we get out of the box two way data binding, that is, if the underlying collection of person objects is modified it is automatically reflected in the UI elements that are bound to it. Likewise if the UI is changed then the underlying collection is also modified. Now that is pretty cool.
If you are interested in the complete source code, please visit my Silverlight gallery there you can see in action two Silverlight data binding applications. Just select Databinding 1 and Databinding 2 from the menu. The first, demos data binding to simple object and the second, demos data binding to a collection of objects. As always the source code to every demo on the gallery is available for download.
Enjoy!
If you are wondering about the chart and expander controls in Databinding 2 gallery demo then visit this codeplex site.
This post was inspired by Jigar Desai post. Check it out.
Guess the movie
I wish I could do something about this. But I can't. But I can promise you two things. One: I'll always look this good. Two: I'll never give up on you... ever.