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 Mark,
Thank you for your post. I have been looking into it and I can say that the XamDataTreeNodesCollection that is iterating in the FindCorespondingNode method is inheriting from CollectionBase class. Here you can find more information about it:
http://msdn.microsoft.com/en-us/library/system.collections.collectionbase.aspx
Also I can say that it is expected to have slow performance when you have a large data-sets and you try to select an object from the end of the collection. I can suggest you use “for” loop, instead of “foreach”, because in the foreach a new instance is created for every item in the collection.
Hope this helps you.
So am I to understand that because XamDataTreeNodesCollection is based on CollectionBase that I cannot use XamDataTree if I must
- bind to the selected node, and select it programatically in my view-model in addition to selecting it in the view with the cursor or mouse- have a medium sized data set of say 5000 - 200,000 lines
that I cannot use your component?That is somewhat hard to believe.
I need an alternative way to select the correct view-item in method "FindCorrespondingNode()" based on the "value" parameter.
Can you think of no alternative? Is there no other way to organise the collection returned by XamDataTree::Nodes()so that random access via the "value" parameter, which is just a reference to my view-model object, is quick and efficient?
Essentially a simple map would do, mapping the <view-model-object-reference> to the <view-item-reference>so that I could, in method "FindCorrespondingNode()", write the following:
private static void FindCorrespondingNode(XamDataTreeNodesCollection nodes, object value) { var node = nodes.GetNode(value); node.IsActive = true; node.IsSelected = true; }
I would create the map myself but I cannot because the reference returned by XamDataTree::Nodes() is never updated.I.e., I could get the nodes in the constructor, and build my own map structure, and use it upon selection.However, if the view-model changes out the tree, which happens often in our app (select a different data-set to display), I would get no notification of that so as to re-build my map.
Cheers,
Mark
As I said it is expected for this method to be slow, becasue there could be a lot of recursive calls. I can log a product idea on your behalf, so either the type of XamDataTreeNodesCollection could be changed or a functioanlity for binding the ActiveDataItem could be added.
Looking forward for your reply.
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
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.
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,
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