Hello!I used the CustomXamDataTree obtained from http://ko.infragistics.com/community/forums/p/58081/296039.aspx#296039(BindingSelectedNode.zip)
This allows me to programmatically select the to-be-selected (active) node in my view-model, and, through data-binding, get the appropriate node in the XamDataTree activated. That works.
However, with data-sets of even a few thousand lines, scrolling becomes ridiculously slow.It seems to be spending much of its time in the FindCorrespondingNode() method, which matches the value object, really my view-model object,with the appropriate node in the XamDataTree, so that it can be selected.This is a recursive method, which check the current node for a match and if one is not found, its children are checked.
Something is going on here in this method! It recurses based on your data-structure "XamDataTreeNodesCollection".Why is it so very slow? What is the data-structure used there? A Map? A List? Just the tree structure itself?
Many thanks,Mark
P.S. The call in "OnPropertyChangedCallback()" to "FindCorrespondingNode()" in my opinion only needs to be called when the user DID NOT click on a graphical tree-node item, but rather only when the View-Model SelectedItem (bound property) is programatically selected. Can you please confirm?
Here is a copy of the code posted in the above-mentioned link:
namespace GraphicalTree{ public class CustomXamDataTree : XamDataTree { private static XamDataTreeNodesCollection nodes; private static bool mMouseLeftButtonDownOrKeyDownCame; public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register( "SelectedItem", typeof(object), typeof(CustomXamDataTree), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnPropertyChangedCallback))); public CustomXamDataTree() { base.ActiveNodeChanged += new EventHandler<ActiveNodeChangedEventArgs>(CustXamDataTree_ActiveNodeChanged); nodes = Nodes; } public static void OnPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { FindCorrespondingNode(nodes, e.NewValue); } void CustXamDataTree_ActiveNodeChanged(object sender, ActiveNodeChangedEventArgs e) { if (e.NewActiveTreeNode != null) SelectedItem = e.NewActiveTreeNode.Data; } public object SelectedItem { get { return (object)GetValue(SelectedItemsProperty); } set { SetValue(SelectedItemsProperty, value); } } private static void FindCorrespondingNode(XamDataTreeNodesCollection nodes, object value) { foreach (XamDataTreeNode node in nodes) { if (node.Data.Equals(value)) { node.IsActive = true; node.IsSelected = true; return; } if (node.HasChildren) { FindCorrespondingNode(node.Nodes, value); } } } }}
Hello,
I can say that in our latest versions (15.1 and 15.2) there is an ActiveDataItem Property, which you can use. Here you can see all the XamDataTree's Properties:
http://help.infragistics.com/Help/Doc/WPF/2015.2/CLR4.0/html/InfragisticsWPF4.Controls.Menus.XamDataTree.v15.2~Infragistics.Controls.Menus.XamDataTree_members.html
Hope this helps you.
Hi Team,
I am using version 12.1 and I am facing similar issue. Have we resolved this issue yet in any of the recent releases or have we added a property ActiveDataItem in recent release that will do the following recursive call efficiently inside Infragistics code.
This is really affecting our delivery in the sprint and I appreciate your response to it.
Hello Mark,
Since ActiveDataItem has been determine as a new Product Idea, I have sent it directly to our product management team. Our product team chooses new Product Ideas for development based on popular feedback from our customer base. Infragistics continues to monitor application development for all of our products, so as trends appear in requested ideas, we can plan accordingly.
We value your input, and our philosophy is to enhance our toolset based on customer feedback. If your idea is chosen for development, you will be notified at that time. Your reference number for this Product Idea is PI13020060.
If you would like to follow up on your Product Idea at a later point, you may contact Developer Support management via email. Please include the reference number of your Product Idea in the subject and body of your email message. You can reach Developer Support management through the following email address: dsmanager@infragistics.com
As for the recursive function, it iterates through all the XamDataTree’s Nodes and since it has hierarchical structure, the best way to iterate its items is by using recursive function.
Well, we would need two things:
- A short-term patch- A longer-term solution
As for your suggestions: both sound good. If IG could add the binding for the ActiveDataItem and do this internally very efficiently (perhaps with internal events or a global node dictionary) so that this was out-of-the-box functionality that we (and everyone else) could use than that of course would be a huge plus.
- I've gotten a few of my colleagues in on the discussion and we would all be very interested to know: what exactly is being done there in all of those recursive calls? What is taking up all the time?
- I need to be able to tell my team-leader that the problem is being worked on (or not!), so I would greatly appreciate a response and perhaps a time-table for a patch and / or long-term fix for this issue.
Regards,Mark
I made this obvious improvement:
private static void FindCorrespondingNode(XamDataTreeNodesCollection nodes, object value, ref bool isFound) { for (var idx = 0; idx < nodes.Count; ++idx) { var node = nodes[idx]; if (node.Data.Equals(value)) { node.IsActive = true; node.IsSelected = true; isFound = true; return; } if (node.HasChildren) { FindCorrespondingNode(node.Nodes, value, ref isFound); if (isFound) <------------------------------- added this return; <------------------------------- added this } } }
This reduces the overhead a lot. Now I see the linearity of the brute-force method used here to find the corresponding node: At the top of the tree the scrolling is slow but better then before.As I go further down in the tree, the performance gets linearly worse until it starts to crawl.
I've enclosed a snapshot of a new profiling session: I clicked once near the top of the tree, then scrolled into the middle with the scrollbar, then turned on the profiling, and profiled one more click on an element.
See "profiling_2.png".
Gentlemen: we need a way to bypass a lot of the stuff that is being called here, and randomly index into a global tree structure!
Cheers,Mark