|
Rank: Newbie Groups: Member
Joined: 3/15/2009 Posts: 7
|
I am using a TreeView which is bound to a DataSource control in VS 2005. AllowDragDrop and AllowDragReordering are set to True so that I can reorder nodes. On postback, I'm using the ItemMoved event to update a sort order field in database records corresponding to the nodes that were moved. The problem is that all nodes moves are not firing the ItemMoved event. For instance, if I have the following nodes in a tree:
Node 1 Node 2 Node 3 Node 4 Node 5 Node 6
And I move the following nodes to anywhere in the list, in the following order:
move node 5 move node 3 move node 6 move node 3 move node 2 move node 1 move node 1
When I set a breakpoint on ItemMoved it only breaks 5 times, not 7, and e.Node equals the following (order sometimes varies):
break 1: Node 3 break 2: Node 5 break 3: Node 1 break 4: Node 6 break 5: Node 2
It's interesting to note that the nodes that are moved twice (3 and 1) only fire ItemMoved once. I'm using a float sort order field in my database records, so I've implemented the great sample you've posted elsewhere to calculate the new sort order number but it does not seem to work when multiple moves happen before a postback. My version of the EO.Web.dll file is version 7.0.27.2. Help please! Thanks.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi, The TreeView merges multiple move events for the same node on purpose because ItemMoved event is fired after all nodes have been moved (Just like TextChanged event is fired after the Text property has already been updated). If we were to fire ItemMoved for every move, then you will get the wrong ParentNode for all but the last move. Consider the following tree view:
Then: 1. Move N4 into N2; 3. Move N4 into N3; When the TreeView is posted back to the server, the TreeView becomes:
The details for the two moves are:
Code:
Node Moved Old Parent Node New Parent Node N4 N1 N2 N4 N2 N3
If we were to fire ItemMoved event for both moves, then you will see:
Code:
Node Moved Old Parent Node New Parent Node N4 N1 N3 N4 N2 N3
The argument for the first move would be wrong. We are not aware this would cause any problems. If it does cause problem for you, it would be very helpful if you can provide a test page and reproduces steps to demonstrate the problem. Once we have that we will try to run it here and see what we can find. Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 3/15/2009 Posts: 7
|
I must be missing something... why wouldn't the first ItemMoved event fire with the correct New Parent Node of N2 for the first move? It seems to me like the ItemMoved event should be a LIFO stack of the correct move data.
Your own demo (Hierarchical DB Update) provides an excellent sample. Reorder several nodes under Local Disk (C:), taking care to move the same node a couple times, postback, and rebind. You will see incorrect results.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Mike wrote:I must be missing something... why wouldn't the first ItemMoved event fire with the correct New Parent Node of N2 for the first move? It seems to me like the ItemMoved event should be a LIFO stack of the correct move data. Because by the time any ItemMoved event is fired the TreeView has already been completely updated. The TreeView is updated before Page_Load so that when Page_Load is fired, the TreeView is "current". However ItemMoved is fired after Page_Load the same manner as many other standard events because many users use Page_Load to initailize certain things and if we fire ItemMoved earlier than that, people will be caught by surpise when they realize that their Page_Load has not been called when ItemMoved is called. By no mean this sequence of Update TreeView -> Page_Load -> ItemMoved is a must, it's just what we observe that can be most convenient to the user. Because by the time ItemMoved is fired, the whole TreeView has already been updated, so when user checks N4's parent node (through ParentNode property) inside the event handler they will always see N3 and never see N2. Please let us know if this makes sense to you. Mike wrote:Your own demo (Hierarchical DB Update) provides an excellent sample. Reorder several nodes under Local Disk (C:), taking care to move the same node a couple times, postback, and rebind. You will see incorrect results. We will look into this and get back to you as soon as possible. Thanks!
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi, We have looked into the issue. The problem can be corrected by adding code at the end of original UpdateSortOrder function to update the TreeNode's Value property as well. So the new function is like this:
Code: C#
private void UpdateSortOrder(EO.Web.TreeNode node)
{
//original code to figure out new sort order....
......
//Update your database....
UpdateSortOrder(nodeId, newSortOrder);
//The following two lines are new
int folderId = int.Parse(node.Value.Split(',')[0]);
node.Value =
string.Format("{0}, {1}", folderId, newSortOrder);
}
The last two lines store the new SortOrder value into the node so that if this node's SortOrder is used later to calculate another node's SortOrder, it will be based on the new value instead of the old value. Please let us know if this works for you. Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 3/15/2009 Posts: 7
|
Let's try a walkthrough with your demo code to see if this works. We'll reorder nodes with sort orders of 1, 2, 3, 4 to 4, 3, 2, 1:
Old value 4 becomes 1.5 (0+3 / 2) Old value 3 becomes 1.75 (1.5+2 / 2) Old value 2 becomes 1.375 (1.75+1 / 2) ***fails
A good idea, but doesn't quite work.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
This does appear to be a problem. The issue doesn't seem to have much to do with merging event but has more to do with the sequence of the event and what's the simplest algorithm to update the least amount of records based on that event sequence. Firing the events faithfully by their original order might solve the problem based on the sample's algorithm, if that's the only option, we will see if we can change the event sequence because allowing you to sync with backend db is one of the main purpose of ItemMoved event.
Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 3/15/2009 Posts: 7
|
Thanks for taking a look at this and your quick feedback... any ideas on when we may see a resolution? I have to come up with an alternate solution and may look at just using an auto-postback for now when a node is moved.
Firing the events in the original order is a step in the right direction but doesn't quite get us there. However, if all node moves are fired in order and could somehow contain a pointer to the next and previous nodes at the time of the move, we might be in business. However, I'm not sure how feasible that would be with whatever code you currently have that stores up the move data.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
We were under the impression as long as:
1. We fire the events in the original order; 2. Fire the event as we are updating the tree, not after we update the tree;
Should solve the problem. However if we wait until the tree has been fully updated then even if we fire all the events in the original order it still won't do. Is condition 2 what you meant by "could somehow contain a pointer to the next and previous nodes at the time of the move"? This means ItemMoved event will be fired before Page_Load.
We are looking forward a new build either at the end of this week or early next week to address this issue.
Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 3/15/2009 Posts: 7
|
I'm not quite sure what happens or what the state of the tree is while you are updating it before Page_Load, but it seems the key is knowing what the prev and next nodes for the moved node were when it was moved. For instance, let's walk through reversing a list of 1,2,3,4 to 4,3,2,1. The move steps would most likely be:
Move 4 to first position Move 3 to second position Move 2 to third position
It seems like each ItemMoved needs to be able to get the following prev/next node info for the "add and divide by 2" reindexing scheme to work:
Move 4, prev of nothing and next of 1 Move 3, prev of 4 (sort order value changed to .5 by ItemMoved code in previous step) and next of 1 Move 2, prev of 3 (sort order value changed to .75 by ItemMoved code in previous step) and next of 1
New sort order values would be .5, .75, .875, 1.
Hope I'm making some sense here. :-) I'll look forward to trying out a new build and should be able to test it as soon as you release it.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
Yes. That makes perfect sense and that's what will happen if we change ItemMoved as described our previous post.
The problem for this approach is "the state of the tree" because we are still in the process of updating it. So certain changes may have not been applied yet. For instance, if user moved a node and edited the node text, by the time ItemMoved is fired, the node text change has not been applied. So if you were to access the node's Text property, you will see the old text instead of the new text. Thus it may open to other issues.
Thanks for offering for testing out. We are still trying to go over all possible options and if nothing else works, we will implement the method you described.
Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 3/15/2009 Posts: 7
|
It doesn't happen often enough these days, so I offer a huge "GREAT JOB" to your company for providing exemplary support on your products. You get my full recommendation and I just sent an email to all of my development friends advocating use of your products. Kudos and just let me know if I can be of further assistance.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Thank you very much for your compliment and recommending our product to your friends! It means a lot to us. We will continue to do our best to provide the best possible product and service to our users.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi Mike,
We have posted a new build that implemented a PreviousNode and NextNode property on TreeNodeMovedEventArgs as you suggested. The event is still fired after Page_Load but two changes have been made:
1. It no longer merges multiple moves of the same node. All moves are fired faithfully as they occurred;
2. You can now get the previous and next sibling node right after the movement of the move;
The sample code is also updated to reflect these changes. We will send the download location to you via PM shortly.
Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 3/15/2009 Posts: 7
|
Just did some testing and it is working great. Thanks so much!
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Great to hear it works for you. Thank you very much for your feedback and help on resolving this issue!
|
|