Data Binding is an important feature for any control specifically for Grid controls. With the advancement of technologies and evolution of Silverlight, DataBinding technologies have provided greater flexibility to present the data to the users in a more processed and systematic way. Silverlight provides lot of DataBinding options like:
- Binding with Static Collection/List
- Binding with XML
- Binding with Database via WCF Services
- Binding with Database via WCF RIA Services
In this blog implementation, we are going to connect a C1FlexGrid to a List collection. Now binding to a simple List Collection is fairly easy. This particular DataBinding implementation goes a step ahead to show the binding with multilevel List collection i.e. List(Of List(of < Type >)). For this implementation, I will keep the structure simple and use List(Of List(Of < Class >)) where Class contains single DataMember of type string . However, the concept remains the same for any variations to this structure. The List of Strings will act as DataContext for each row Cell. Each Cell will host a child C1FlexGrid and assigned this List of string as DataSource. Lets see the step by step implementation.
Define the Class structure
Public Class myDataClass Dim _name As String Public Sub New(ByVal _nm As String) \_name = \_nm End Sub Public Property Name() As String Get Return _name End Get Set(value As String) _name = value End Set End Property End Class
Create Class structure returning List In this Class, DataMember is a list of myDataClass which will act as DataSource for each Row in C1FlexGrid.
Public Class mainDataClassCollection Dim _list As List(Of myDataClass) Public Sub New(ByVal index As Integer) _list = New List(Of myDataClass) For i As Integer = 0 To 2 _list.Add(New myDataClass("Name " + index.ToString() + i.ToString())) Next End Sub Public ReadOnly Property ListData() As List(Of myDataClass) Get Return _list End Get End Property End Class
Add Column to C1FlexGrid
You can define a Column either in XAML or through code.
c1FlexGrid1.AutoGenerateColumns = False Dim column As New C1.Silverlight.FlexGrid.Column column.Header = "List Names" c1FlexGrid1.Columns.Add(column) BindGrid()
In the above code, you would observe the call for module 'BindGrid()'. This module defines the binding for the C1FlexGrid column.
Private Sub BindGrid() Dim _mainDataList As New List(Of mainDataClassCollection) For i As Integer = 0 To 5 _mainDataList.Add(New mainDataClassCollection(i)) Next Dim bnd As New System.Windows.Data.Binding bnd.Path = New PropertyPath("ListData") bnd.Mode = Data.BindingMode.TwoWay bnd.UpdateSourceTrigger = Data.UpdateSourceTrigger.Default c1FlexGrid1.Columns(0).Binding = bnd c1FlexGrid1.CellFactory = New MyCellFactory() c1FlexGrid1.ItemsSource = _mainDataList c1FlexGrid1.AutoSizeColumns(0, 0, 0) c1FlexGrid1.AutoSizeRows(0, c1FlexGrid1.Rows.Count - 1, 0) End Sub
After implementing all the above steps, if you run the sample, data will be displayed incorrectly as shown below. This occurs due to the fact that Data for the cell is a List Collection and cell is unable to resolve the type to match the basic DataTypes supported.
Use CellFactory to change the Cell Content
CellFactory is the most important feature of C1FlexGrid when it comes to the customization of the control. It provides the flexibility to override the existing modules to modify the look at various levels of Grid rendering. For ex. CreateColumnHeaderContent can be used to customize when Header Cell is rendered. Similarly we have several such modules. In this scenario, we use CreateCellContent event to customize the Cell Content to replace the TextBlock with C1FlexGrid for the display of List Collection inside the cell.
Public Class MyCellFactory Inherits C1.Silverlight.FlexGrid.CellFactory Public Overrides Sub CreateCellContent(grid As C1.Silverlight.FlexGrid.C1FlexGrid, bdr As System.Windows.Controls.Border, rng As C1.Silverlight.FlexGrid.CellRange) MyBase.CreateCellContent(grid, bdr, rng) Dim chFlx As New C1.Silverlight.FlexGrid.C1FlexGrid chFlx.ItemsSource = CType(grid.Rows(rng.Row).DataItem, mainDataClassCollection).ListData chFlx.HeadersVisibility = C1.Silverlight.FlexGrid.HeadersVisibility.None grid.Rows(rng.Row).Height = 72 chFlx.AutoSizeRows(0, chFlx.Rows.Count - 1, 0) chFlx.AutoSizeColumns(0, 0, 0) bdr.Child = chFlx End Sub
Assign this CellFactory object to Original C1Flexgrid control.
c1FlexGrid1.CellFactory = New MyCellFactory()