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