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

NodesNeeded event gets executed on unwanted occasions

5 Answers 114 Views
Treeview
This is a migrated thread and some comments may be shown as answers.
Georges
Top achievements
Rank 1
Georges asked on 28 Dec 2020, 06:58 PM

Hello,

I want to use the LoadOnDemand feature of the RadTreeView.

But the NodesNeeded event gets executed on unwanted occasions, such as if I set the form's Enabled property to False, if I use the FindNodes method, or if I refer to the RadTreeview control.

The utility of loading on demand then becomes a defect for me.

It would be good if this event was executed only once, when you want to load the node.

Am I doing something wrong?

Excuse my English. I am Francophone.

Thank you

5 Answers, 1 is accepted

Sort by
0
Nadya | Tech Support Engineer
Telerik team
answered on 29 Dec 2020, 10:00 AM

Hello, Georges,

NodesNeeded event is raised only for the expanded parent node. Thus, you can fill the parent nodes with sub-nodes.

RadTreeView supports two modes of lazy loading nodes:
- Full lazy mode: In this mode, the NodesNeeded event is fired when you try to expand a node. Before expanding a node, RadTreeView is not aware whether this node has children or not. Therefore, you get expander signs for all nodes, regardless of whether these nodes will provide data when the end-user will try to expand them. To enable this feature, you should set the LazyMode to true.

- Partial lazy mode: This is the default mode of RadTreeView. In this mode, the NodesNeeded event is fired for all directly accessible nodes without any action required from the end-user. When the end-user expands a node, the NodesNeeded event is fired for the sub-nodes of this node. In short, you are filling the first sub-level of a parent node in advance. Because of that, the parent nodes are aware of whether they have child nodes or not, and as a result, RadTreeView can determine whether an expander sign is required or not. To enable this feature, you should set the LazyMode property to false.

Additional information is available here: https://docs.telerik.com/devtools/winforms/controls/treeview/data-binding/load-on-demand 

I have attached a sample project to this thread. If you add a breakpoint in the NodesNeeded event you can see that it fires only once when expanding a parent node. Can you give the provided project a try and see how it works? Am I missing something?

I am looking forward to your reply.

Regards,
Nadya
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Georges
Top achievements
Rank 1
answered on 29 Dec 2020, 06:29 PM

Hello Nadsya,

Thanks for your following along!

I checked with the example provided on:
https://docs.telerik.com/devtools/winforms/controls/treeview/data-binding/load-on-demand

If I use the example with LazyMode = False. The NodesNeeded event is executed again each time when clicking on an already deployed node. Same thing if we reduce a deployed node. Same thing if we use Me.RadTreeView1.SelectedNode.GetNodeCount (includeSubTrees: = False).

This behavior makes it difficult to use this feature of your RadTreeView, for my project so I'll use a load on NodeMouseClick or bind the RadTreeView to a DataSource.

With LazyMode = True it's ok, NodesNeeded is executed just as needed.

But I need to use LazyMode = False ...

Note that with LazyMode = True or Flase, a System.OverflowException error occurs if using Me.RadTreeView1.SelectedNode.GetNodeCount (includeSubTrees: = True).

0
Georges
Top achievements
Rank 1
answered on 29 Dec 2020, 06:34 PM

Oups, Translator rename you...

I had prepared an example, but I cannot send you this type of file.

 

RadForm1.vb

Imports Telerik.WinControls.UI
Public Class RadForm1
    Private Sub radTreeView1_NodesNeeded(ByVal sender As Object, ByVal e As NodesNeededEventArgs) Handles RadTreeView1.NodesNeeded
        Me.rtbNodesNeeded.Text = Val(Me.rtbNodesNeeded.Text) + 1

        If e.Parent Is Nothing Then
            LoadRootNodes(e.Nodes)
            Return
        End If

        ' If the parent node is one of the "My Computer" children, 
        ' then add sub-nodes to this node depending on its index
        If e.Parent.Level = 1 Then
            If e.Parent.Index Mod 3 = 0 Then
                Return
            End If
        End If

        For i As Integer = 0 To 4
            Dim childNode As New RadTreeNode(String.Format("Node{0}", i))
            e.Nodes.Add(childNode)
        Next i
    End Sub

    Private Sub LoadRootNodes(ByVal nodes As IList(Of RadTreeNode))
        Dim mcNode As New RadTreeNode("My Computer")
        Me.rtbLoadRootNodes.Text = Val(Me.rtbLoadRootNodes.Text) + 1
        nodes.Add(mcNode)
    End Sub

    Private Sub RadForm1_Load(sender As Object, e As EventArgs) Handles Me.Load
        Me.RadTreeView1.LazyMode = False
    End Sub

    Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click
        If Me.RadTreeView1.SelectedNode Is Nothing Then
            Me.RadTreeView1.Nodes(0).Selected = True
        End If
        Me.rtbNodesCount.Text = Me.RadTreeView1.SelectedNode.GetNodeCount(includeSubTrees:=True)
    End Sub

    Private Sub RadButton2_Click(sender As Object, e As EventArgs) Handles RadButton2.Click
        If Me.RadTreeView1.SelectedNode Is Nothing Then
            Me.RadTreeView1.Nodes(0).Selected = True
        End If
        Me.rtbNodesCount.Text = Me.RadTreeView1.SelectedNode.GetNodeCount(includeSubTrees:=False)
    End Sub
End Class

 

0
Georges
Top achievements
Rank 1
answered on 29 Dec 2020, 06:35 PM

RadForm1.Designer.vb

 

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class RadForm1
    Inherits Telerik.WinControls.UI.RadForm

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.RadTreeView1 = New Telerik.WinControls.UI.RadTreeView()
        Me.RadLabel1 = New Telerik.WinControls.UI.RadLabel()
        Me.rtbLoadRootNodes = New Telerik.WinControls.UI.RadTextBox()
        Me.rtbNodesNeeded = New Telerik.WinControls.UI.RadTextBox()
        Me.RadLabel2 = New Telerik.WinControls.UI.RadLabel()
        Me.RadButton1 = New Telerik.WinControls.UI.RadButton()
        Me.rtbNodesCount = New Telerik.WinControls.UI.RadTextBox()
        Me.RadButton2 = New Telerik.WinControls.UI.RadButton()
        CType(Me.RadTreeView1, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.RadLabel1, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.rtbLoadRootNodes, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.rtbNodesNeeded, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.RadLabel2, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.RadButton1, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.rtbNodesCount, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.RadButton2, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'RadTreeView1
        '
        Me.RadTreeView1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
            Or System.Windows.Forms.AnchorStyles.Left) _
            Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.RadTreeView1.Location = New System.Drawing.Point(12, 68)
        Me.RadTreeView1.Name = "RadTreeView1"
        Me.RadTreeView1.Size = New System.Drawing.Size(475, 284)
        Me.RadTreeView1.SpacingBetweenNodes = -1
        Me.RadTreeView1.TabIndex = 0
        '
        'RadLabel1
        '
        Me.RadLabel1.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.RadLabel1.Location = New System.Drawing.Point(168, 367)
        Me.RadLabel1.Name = "RadLabel1"
        Me.RadLabel1.Size = New System.Drawing.Size(89, 18)
        Me.RadLabel1.TabIndex = 1
        Me.RadLabel1.Text = "LoadRootNodes:"
        '
        'rtbLoadRootNodes
        '
        Me.rtbLoadRootNodes.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.rtbLoadRootNodes.Location = New System.Drawing.Point(275, 366)
        Me.rtbLoadRootNodes.Name = "rtbLoadRootNodes"
        Me.rtbLoadRootNodes.ReadOnly = True
        Me.rtbLoadRootNodes.Size = New System.Drawing.Size(50, 20)
        Me.rtbLoadRootNodes.TabIndex = 2
        Me.rtbLoadRootNodes.Text = "0"
        Me.rtbLoadRootNodes.TextAlign = System.Windows.Forms.HorizontalAlignment.Right
        '
        'rtbNodesNeeded
        '
        Me.rtbNodesNeeded.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.rtbNodesNeeded.Location = New System.Drawing.Point(101, 366)
        Me.rtbNodesNeeded.Name = "rtbNodesNeeded"
        Me.rtbNodesNeeded.ReadOnly = True
        Me.rtbNodesNeeded.Size = New System.Drawing.Size(50, 20)
        Me.rtbNodesNeeded.TabIndex = 4
        Me.rtbNodesNeeded.Text = "0"
        Me.rtbNodesNeeded.TextAlign = System.Windows.Forms.HorizontalAlignment.Right
        '
        'RadLabel2
        '
        Me.RadLabel2.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.RadLabel2.Location = New System.Drawing.Point(14, 366)
        Me.RadLabel2.Name = "RadLabel2"
        Me.RadLabel2.Size = New System.Drawing.Size(81, 18)
        Me.RadLabel2.TabIndex = 3
        Me.RadLabel2.Text = "NodesNeeded:"
        '
        'RadButton1
        '
        Me.RadButton1.Location = New System.Drawing.Point(10, 36)
        Me.RadButton1.Name = "RadButton1"
        Me.RadButton1.Size = New System.Drawing.Size(402, 24)
        Me.RadButton1.TabIndex = 7
        Me.RadButton1.Text = "GetNodeCount(includeSubTrees:=True) cause a System.OverflowException"
        '
        'rtbNodesCount
        '
        Me.rtbNodesCount.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.rtbNodesCount.Location = New System.Drawing.Point(437, 8)
        Me.rtbNodesCount.Name = "rtbNodesCount"
        Me.rtbNodesCount.ReadOnly = True
        Me.rtbNodesCount.Size = New System.Drawing.Size(50, 20)
        Me.rtbNodesCount.TabIndex = 9
        Me.rtbNodesCount.Text = "0"
        Me.rtbNodesCount.TextAlign = System.Windows.Forms.HorizontalAlignment.Right
        '
        'RadButton2
        '
        Me.RadButton2.Location = New System.Drawing.Point(12, 6)
        Me.RadButton2.Name = "RadButton2"
        Me.RadButton2.Size = New System.Drawing.Size(329, 24)
        Me.RadButton2.TabIndex = 10
        Me.RadButton2.Text = " Me.RadTreeView1.GetNodeCount(includeSubTrees:=False)"
        '
        'RadForm1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(499, 398)
        Me.Controls.Add(Me.rtbNodesCount)
        Me.Controls.Add(Me.RadButton2)
        Me.Controls.Add(Me.RadButton1)
        Me.Controls.Add(Me.rtbNodesNeeded)
        Me.Controls.Add(Me.RadLabel2)
        Me.Controls.Add(Me.rtbLoadRootNodes)
        Me.Controls.Add(Me.RadLabel1)
        Me.Controls.Add(Me.RadTreeView1)
        Me.Name = "RadForm1"
        '
        '
        '
        Me.RootElement.ApplyShapeToControl = True
        Me.Text = "RadForm1"
        CType(Me.RadTreeView1, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.RadLabel1, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.rtbLoadRootNodes, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.rtbNodesNeeded, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.RadLabel2, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.RadButton1, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.rtbNodesCount, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.RadButton2, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub

    Friend WithEvents RadTreeView1 As Telerik.WinControls.UI.RadTreeView
    Friend WithEvents RadLabel1 As Telerik.WinControls.UI.RadLabel
    Friend WithEvents rtbLoadRootNodes As Telerik.WinControls.UI.RadTextBox
    Friend WithEvents rtbNodesNeeded As Telerik.WinControls.UI.RadTextBox
    Friend WithEvents RadLabel2 As Telerik.WinControls.UI.RadLabel
    Friend WithEvents RadButton1 As Telerik.WinControls.UI.RadButton
    Friend WithEvents rtbNodesCount As Telerik.WinControls.UI.RadTextBox
    Friend WithEvents RadButton2 As Telerik.WinControls.UI.RadButton
End Class

0
Nadya | Tech Support Engineer
Telerik team
answered on 30 Dec 2020, 03:34 PM

Hello, Georges,

Thank you for the provided code snippets from your project. I was able to use them and construct the project that reproduces the case that you have. This is normal behavior when you use the load-on-demand approach with LazyMode = False you are providing the nodes in the NodesNeeded event. Then, it is expected the NodesNeeded event to fire. In your case, you are always providing nodes and the number of nodes is infinitely increasing. This is why the exception occurs. For example, if you limit the parent level to 5 you will have 11720 nodes and no exception occurs.

If e.Parent.Level > 5 Then
    Return
End If

Please refer to the modified project attached to this thread. 

I hope this helps. Should you have other questions please let me know.

Regards,
Nadya
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Treeview
Asked by
Georges
Top achievements
Rank 1
Answers by
Nadya | Tech Support Engineer
Telerik team
Georges
Top achievements
Rank 1
Share this question
or