Hello!I used the CustomXamDataTree obtained from http://es.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