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:

  1. Binding with Static Collection/List

  2. Binding with XML

  3. Binding with Database via WCF Services

  4. 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()


Binding C1FlexGrid



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()


Finally we will have the output as shown in the image below.



You can download the attached samples for complete implementation.

Download Sample VB
Download Sample C#