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

LoadOnDemand Hierarchy with Await/Async in RowSourceNeeded Event.

3 Answers 145 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Sameh
Top achievements
Rank 1
Sameh asked on 04 Oct 2018, 05:17 PM

Hi, 

I have a simple grid with 1 field in the master template, and one field in the child template. I want to use the load on demand, the solution works fine without await/async:

 

 

Private Async Sub RadGridView1_RowSourceNeeded(sender As Object, e As GridViewRowSourceNeededEventArgs) Handles RadGridView1.RowSourceNeeded
      'Add 3 sub rows
       Dim row1 As GridViewRowInfo = e.Template.Rows.NewRow
       row1.Cells(0).Value = "Test 1"
       e.SourceCollection.Add(row1)
 
       Dim row2 As GridViewRowInfo = e.Template.Rows.NewRow
       row2.Cells(0).Value = "Test 2"
       e.SourceCollection.Add(row2)
 
       Dim row3 As GridViewRowInfo = e.Template.Rows.NewRow
       row3.Cells(0).Value = "Test 3"
       e.SourceCollection.Add(row3)
   End Sub

 

 

However, when I use await with the event, the parent row does not auto expand, and the behavior become weird when trying to select child row there is a lot of scrolling and flickering:

 

Private Async Sub RadGridView1_RowSourceNeededAsync(sender As Object, e As GridViewRowSourceNeededEventArgs) Handles RadGridView1.RowSourceNeeded
         
'Simulate Await
        Await Task.Delay(1000)
 
        Dim row1 As GridViewRowInfo = e.Template.Rows.NewRow
        row1.Cells(0).Value = "Test 1"
        e.SourceCollection.Add(row1)
 
        Dim row2 As GridViewRowInfo = e.Template.Rows.NewRow
        row2.Cells(0).Value = "Test 2"
        e.SourceCollection.Add(row2)
 
        Dim row3 As GridViewRowInfo = e.Template.Rows.NewRow
        row3.Cells(0).Value = "Test 3"
        e.SourceCollection.Add(row3)
    End Sub

 

Many Thanks

Sameh

3 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 05 Oct 2018, 10:18 AM
Hello, Sameh, 

The RadGridView.RowSourceNeeded event is used to load the data rows for the child template only when they are required. However, if you performed some delayed execution, it would be necessary to force refreshing the grid. You can find below an updated code snippet which result is illustrated in the attached gif file:
Sub New()
    InitializeComponent()
 
    Me.RadGridView1.Columns.Add("Description")
    Me.RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
    Me.RadGridView1.MasterTemplate.Rows.Add("Item 1")
 
    Dim childTemplate As New GridViewTemplate()
    childTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
    Dim namecolumn As New GridViewTextBoxColumn("Name")
    Dim productNumberColumn As New GridViewTextBoxColumn("ProductNumber")
    childTemplate.Columns.AddRange(namecolumn, productNumberColumn)
 
    Me.RadGridView1.Templates.Add(childTemplate)
    childTemplate.HierarchyDataProvider = New GridViewEventDataProvider(childTemplate)
    AddHandler RadGridView1.RowSourceNeeded, AddressOf radGridView1_RowSourceNeeded
 
End Sub
 
Private Async Sub radGridView1_RowSourceNeeded(sender As Object, e As GridViewRowSourceNeededEventArgs)
    Await Task.Delay(1000)
 
    Dim row As GridViewRowInfo = e.Template.Rows.NewRow()
    row.Cells("Name").Value = "Item " & DateTime.Now.ToLongTimeString()
    row.Cells("ProductNumber").Value = DateTime.Now.TimeOfDay.TotalSeconds
 
    e.SourceCollection.Add(row)
 
    row = e.Template.Rows.NewRow()
    row.Cells("Name").Value = "Item " & DateTime.Now.ToLongTimeString()
    row.Cells("ProductNumber").Value = DateTime.Now.TimeOfDay.TotalSeconds
 
    e.SourceCollection.Add(row)
 
    Me.RadGridView1.MasterTemplate.Refresh()
End Su

I hope this information helps.

Regards,
Dess
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
Sameh
Top achievements
Rank 1
answered on 05 Oct 2018, 12:05 PM

Hello Dess, 

Thank you for your quick response, 

Your proposed solution partially resolved the issue, however when you have scrollbar, there is  a flicker / autoscrolling when using await/async.

In the following example, expand the first 2 rows, then try to select any child and you will notice the scrolling issue, if you remove Await/Async, the grid works perfectly.

 

Imports Telerik.WinControls.UI
 
Public Class Form1
    Public Sub New()
        InitializeComponent()
        Me.RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
        RadGridView1.AutoGenerateColumns = False
        GridViewTemplate1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
        GridViewTemplate1.HierarchyDataProvider = New GridViewEventDataProvider(GridViewTemplate1)
 
        Dim c As New List(Of Sam)
 
        c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
        c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
        c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
        c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
        c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
        c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
        c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
        c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
 
 
        RadGridView1.DataSource = c
    End Sub
 
    Private Async Sub RadGridView1_RowSourceNeededAsync(sender As Object, e As GridViewRowSourceNeededEventArgs) Handles RadGridView1.RowSourceNeeded
        Await Task.Delay(1000)
        Dim row1 As GridViewRowInfo = e.Template.Rows.NewRow
        row1.Cells(0).Value = "Test 1"
        e.SourceCollection.Add(row1)
 
        Dim row2 As GridViewRowInfo = e.Template.Rows.NewRow
        row2.Cells(0).Value = "Test 2"
        e.SourceCollection.Add(row2)
 
        Dim row3 As GridViewRowInfo = e.Template.Rows.NewRow
        row3.Cells(0).Value = "Test 3"
        e.SourceCollection.Add(row3)
        Me.RadGridView1.MasterTemplate.Refresh()
 
        Dim row4 As GridViewRowInfo = e.Template.Rows.NewRow
        row4.Cells(0).Value = "Test 4"
        e.SourceCollection.Add(row4)
        Me.RadGridView1.MasterTemplate.Refresh()
    End Sub
 
 
End Class
 
Public Class Sam
    Property C1 As String
    Property C2 As String
End Class

 

Note: MasterTemplate has 2 cols, sub template has 1 col.

Thanks

Sameh

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 09 Oct 2018, 08:24 AM
Hello, Sameh, 

It is normal to obtain a little flicker when you refresh the MasterTemplate. As a result the vertical scrollbar will be also return back to the top. However, you can store the position of the scrollbar before performing the refresh operation and then restore it. But when you use asynchronous loading of the child rows, it is not very easy to determine when the asynchronous operation is finished. You can use the following code snippet which result is illustrated in the attached gif file: 
Sub New()
     InitializeComponent()
 
     Me.RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
     RadGridView1.AutoGenerateColumns = True
     Dim GridViewTemplate1 As New GridViewTemplate
     GridViewTemplate1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
     Dim namecolumn As New GridViewTextBoxColumn("Name")
     Dim productNumberColumn As New GridViewTextBoxColumn("ProductNumber")
     GridViewTemplate1.Columns.AddRange(namecolumn, productNumberColumn)
 
     Me.RadGridView1.Templates.Add(GridViewTemplate1)
      
     GridViewTemplate1.HierarchyDataProvider = New GridViewEventDataProvider(GridViewTemplate1)
 
     Dim c As New List(Of Sam)
 
     c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
     c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
     c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
     c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
     c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
     c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
     c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
     c.Add(New Sam With {.C1 = 1, .C2 = "Hello"})
 
 
     RadGridView1.DataSource = c
 
 End Sub
 
 Dim value As Integer
 Private Async Sub RadGridView1_RowSourceNeededAsync(sender As Object, e As GridViewRowSourceNeededEventArgs) Handles RadGridView1.RowSourceNeeded
     AddHandler Me.RadGridView1.TableElement.VScrollBar.ValueChanged, AddressOf VScrollBar_ValueChanged
     value = Me.RadGridView1.TableElement.VScrollBar.Value
 
     Await Task.Delay(1000)
     Dim row1 As GridViewRowInfo = e.Template.Rows.NewRow
     row1.Cells(0).Value = "Test 1"
     e.SourceCollection.Add(row1)
 
     Dim row2 As GridViewRowInfo = e.Template.Rows.NewRow
     row2.Cells(0).Value = "Test 2"
     e.SourceCollection.Add(row2)
 
     Dim row3 As GridViewRowInfo = e.Template.Rows.NewRow
     row3.Cells(0).Value = "Test 3"
     e.SourceCollection.Add(row3)
     Me.RadGridView1.MasterTemplate.Refresh()
 
     Dim row4 As GridViewRowInfo = e.Template.Rows.NewRow
     row4.Cells(0).Value = "Test 4"
     e.SourceCollection.Add(row4)
       
     RemoveHandler Me.RadGridView1.TableElement.VScrollBar.ValueChanged, AddressOf VScrollBar_ValueChanged
 End Sub
 
 Public Class Sam
     Property C1 As String
     Property C2 As String
 End Class
 
 Private Sub VScrollBar_ValueChanged(sender As Object, e As EventArgs)
     If value > 0 Then
         RemoveHandler Me.RadGridView1.TableElement.VScrollBar.ValueChanged, AddressOf VScrollBar_ValueChanged
         Me.RadGridView1.TableElement.VScrollBar.Value = value
     End If
 End Sub

Note that this is just a sample approach and it may not cover all possible cases. Feel free to modify it in a way which suits your requirement best.

Regards,
Dess
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
Sameh
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Sameh
Top achievements
Rank 1
Share this question
or