This is a migrated thread and some comments may be shown as answers.

Parent data is nothing in multilevel hierarchy GridView

3 Answers 74 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Kun
Top achievements
Rank 2
Kun asked on 09 Jan 2019, 04:33 PM

Hello,
There are 3 hierarchical levels in my grid. I use "Load-on-Demand" method to load hierarchical data. Mastertemplate data is binding to a local collection.

My gridview is built basically like this :
   Private Sub FrmMain_Load(sender As Object, e As EventArgs)

        myGridView.MultiSelect = True
        myGridView.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
        myGridView.ReadOnly = True
        myGridView.AllowRowResize = False
        myGridView.MasterTemplate.SelectionMode = GridViewSelectionMode.FullRowSelect
        myGridView.UseScrollbarsInHierarchy = True
        myGridView.MasterTemplate.ShowChildViewCaptions = True
        myGridView.MasterTemplate.ShowRowHeaderColumn = False

        Call Load_Hierarchy()

        AddHandler myGridView.RowSourceNeeded, AddressOf myGridView_RowSourceNeeded

        myBase.Charge()

        myGridView.DataSource =myBase

   End Sub

   Private Sub Load_Hierarchy()

       Dim template_FirstLevel As New GridViewTemplate()
        template_FirstLevel .Caption = "FirstLevel"
        template_FirstLevel .AllowAddNewRow = False
        template_FirstLevel .AllowDeleteRow = False
        template_FirstLevel .AllowEditRow = False
        template_FirstLevel .AllowRowResize = False
        template_FirstLevel .AutoGenerateColumns = False
        template_FirstLevel .AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
        template_FirstLevel .ShowChildViewCaptions = True
        template_FirstLevel .ShowRowHeaderColumn = False
        Dim gCol_1 As GridViewTextBoxColumn = New GridViewTextBoxColumn("Col1")

        Dim gCol_2 As GridViewTextBoxColumn = New GridViewTextBoxColumn("Col2")        

        template_FirstLevel.Columns.AddRange(New GridViewDataColumn() {gCol_1, gCol_2})
        myGridView.MasterTemplate.Templates.Add(template_FirstLevel )
        template_FirstLevel.HierarchyDataProvider = New GridViewEventDataProvider(template_FirstLevel)

        '-------------------definition of Second Level template
        Dim template_2ndLevel As New GridViewTemplate()
        template_2ndLevel.Caption = "Second Level"
        template_2ndLevel.AllowAddNewRow = False
        template_2ndLevel.AllowDeleteRow = False
        template_2ndLevel.AllowEditRow = False
        template_2ndLevel.AutoGenerateColumns = False
        template_2ndLevel.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill
        template_2ndLevel.ShowChildViewCaptions = True
        template_2ndLevel.ShowRowHeaderColumn = False
        Dim gCol_2nd1 As GridViewTextBoxColumn = New GridViewTextBoxColumn("Index")
        Dim gCol_2nd2 As GridViewTextBoxColumn = New GridViewTextBoxColumn("Name")
        template_2ndLevel.Columns.AddRange(New GridViewDataColumn() {gCol_2nd1 , gCol_2nd2})
        template_FirstLevel.Templates.Add(template_2ndLevel)
        template_2ndLevel.HierarchyDataProvider = New GridViewEventDataProvider(template_2ndLevel)

   End Sub

   Private Sub myGridView_RowSourceNeeded(sender As Object, e As GridViewRowSourceNeededEventArgs)
        If e.ParentRow.HierarchyLevel = 0 Then '----First Level data load
            Dim Masteritem As C_dbProduit = TryCast(e.ParentRow.DataBoundItem, C_Master)

                    ------Do something to load data in FirstLevelItemsList by using Masteritem-------
                    For 1stItem fonction In FirstLevelItemsList
                        Dim row_1stL As GridViewRowInfo = e.Template.Rows.NewRow()
                        row_1stL.Cells("Col1").Value = 1stItem.data1
                        row_1stL.Cells("Col2").Value = 1stItem.data2                        
                        e.SourceCollection.Add(row_1stL)
                    Next

        End If

        If e.ParentRow.HierarchyLevel = 1 Then '----2nd Level data load
                Dim 1stItem As C_1stItem = TryCast(e.ParentRow.DataBoundItem, C_1stItem)

                Dim masterparentRow As GridViewRowInfo = TryCast(e.ParentRow.Parent, GridViewRowInfo)
                Dim masteritem As C_Master = TryCast(parentRow.DataBoundItem, C_Master)

                If 1stItem Is Nothing Then '-----------------e.ParentRow.DataBoundItem is always nothing
                       Exit Sub
                End If

                If masteritem Is Nothing Then'-----------------e.ParentRow.Parent.DataBoundItem is always Correct!
                       Exit Sub

                End If

                '------------Do something to load data in the collection of 2ndItem by using 1stItem-------

        End If

    End Sub

It works perfect to show mastertemplate and 1st hierarchical level. But when I expand 2nd level, its ParentRow.DataBoundItem (it should be selected 1st level data) is always nothing. But I can get DataBoundItem of e.ParentRow.Parent correctly.

In order to avoid memory overloading, I prefer load-on-demand method in hierarchy grid.

Please help me.

Thank you

3 Answers, 1 is accepted

Sort by
0
Accepted
Hristo
Telerik team
answered on 10 Jan 2019, 11:49 AM
Hello Kun,

The observed behavior is expected because actually, your first child template remains unbound. That is why when you access the DataBoundItem property of the parent row it is null. A possible solution is to save the data-bound object in the Tag property of the of the rows when creating them for the first template in the RowSourceNeeded event. I have created a sample project using the Northwind database. Please also check my code snippet below: 
Private Sub radGridView1_RowSourceNeeded(sender As Object, e As GridViewRowSourceNeededEventArgs)
    If e.Template.HierarchyLevel = 1 Then
        Dim rowView As DataRowView = TryCast(e.ParentRow.DataBoundItem, DataRowView)
        Dim rows() As DataRow = rowView.Row.GetChildRows("CustomersOrders")
 
        For Each dataRow As DataRow In rows
            Dim row As GridViewRowInfo = e.Template.Rows.NewRow()
            row.Tag = dataRow
            row.Cells("OrderID").Value = dataRow("OrderID")
            row.Cells("CustomerID").Value = dataRow("CustomerID")
            row.Cells("OrderDate").Value = dataRow("OrderDate")
            e.SourceCollection.Add(row)
        Next dataRow
    Else
        Dim parentDataRow As DataRow = Nothing
        Dim rowView As DataRowView = TryCast(e.ParentRow.DataBoundItem, DataRowView)
        If rowView IsNot Nothing Then
            parentDataRow = rowView.Row
        Else
            parentDataRow = e.ParentRow.Tag
        End If
 
        Dim rows() As DataRow = parentDataRow.GetChildRows("OrdersOrder Details")
        For Each dataRow As DataRow In rows
            Dim row As GridViewRowInfo = e.Template.Rows.NewRow()
            row.Cells("OrderID").Value = dataRow("OrderID")
            row.Cells("ProductID").Value = dataRow("ProductID")
            row.Cells("Quantity").Value = dataRow("Quantity")
 
            e.SourceCollection.Add(row)
        Next dataRow
    End If
 
End Sub

I hope this will help. Let me know if you need further assistance.

Regards,
Hristo
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Kun
Top achievements
Rank 2
answered on 10 Jan 2019, 03:37 PM
Thank you, Hristo. Such a good idea. I'll try it.
0
Hristo
Telerik team
answered on 11 Jan 2019, 06:42 AM
Hello Kun,

I hope that a similar solution would fit your local setup. Let me know if you need further assistance.

Regards,
Hristo
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
GridView
Asked by
Kun
Top achievements
Rank 2
Answers by
Hristo
Telerik team
Kun
Top achievements
Rank 2
Share this question
or