Silverlight FlexGrid Binding to MultiLevel List Collection

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

  End Sub  

  Public ReadOnly Property ListData() As List(Of myDataClass)  
        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"  


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

   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#


GrapeCity Developer Tools
comments powered by Disqus