We use Telerik UI for Winforms extensively in our Windows application. We have migrated almost all of our UI to use Telerik UI for Winforms but we were using a 2014 release of Telerik. Last month we updated to the latest (Q1 2022) Telerik UI for Winforms and began converting the last 3 major tree controls in our UI to use the RadTreeView. The biggest of these tree controls can have a lot of nodes. Some of our customers will exceed 750000 nodes in their installations.
We have found that when sorting is enabled, especially our custom sort which is necessary for our implementation, the tree control takes a VERY long time to load and also a very long time to repopulate when a leaf node with its children is removed and then re-added. Of note when we remove/re-add a leaf node is that if I put a breakpoint into our NodeComparer implementation I see that many nodes from all over the tree are being compared. The comparisons include nodes that are at the root of the tree and were not affected since the node(s) removed were 4 or 5 levels down and restricted in scope to just one sub-collection. I am very surprised that the RadTreeView re-sorts ALL of the tree nodes rather than just the nodes in the affected collection?
Are there ways to restrict sorting to just the collection affected by the addition/removal of a node?
Out of curiosity I disabled all sorting on the primary tree control that we are converting to RadTreeView. In spite of removing the sorting, adding nodes to this tree is still really slow.
A common action in our software is to "regenerate" a group of nodes representing devices on the network. In this scenario a number of nodes are removed and then a new set of nodes are added back to the tree based on newly acquired data.
I found that if I regenerated a network (containing devices, object groups and objects) then adding 693 "object" nodes into 15 "group" nodes below just one "device" node took 119,651,964 ticks! If I added a call to Nodes.DeferRefresh() (see code below) then the time taken dropped to 660,000-700,000 ticks. That's a 170x or better improvement. The problem is, I don't actually know what side effects I'm going to get from DeferRefresh().
if (objectNode != null) { if (objectNode.ObjectType != BACstac_Object_Type.Device) { #region Find or Create Group Node Type groupType = null; if (getGroupType(VendorID, ModelName, FirmwareRevision, objectRow.ObjectType, objectRow.ObjectInstanceID, out groupType, out errorMessage) == false) { //TODO: This is a problem OutputWindow.addMessage(OutputWindow._OutputType.Error, @"Did not find a group type for " + objectRow.ObjectType.ToString(), @"Network Manager"); continue; } BACnetObjectGroupNode groupNode = null; if (m_objectGroups.TryGetValue(groupType, out groupNode) == false) { System.Reflection.ConstructorInfo info = groupType.GetConstructor(paramTypesArray); groupNode = info.Invoke(parametersArray) as BACnetObjectGroupNode; m_objectGroups.Add(groupType, groupNode); Nodes.DeferRefresh(); Nodes.Add(groupNode); } groupNode.Nodes.DeferRefresh(); groupNode.Nodes.Add(objectNode); #endregion } newObjectList.Add(objectNode); }