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