This is a migrated thread and some comments may be shown as answers.

Context menu reference (by index) to node might need to be rethought

5 Answers 59 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Shukhrat Nekbaev
Top achievements
Rank 1
Shukhrat Nekbaev asked on 14 Oct 2011, 01:11 PM
Hi,

Background:
in my asp.net 4.0 app (ajaxified) I reload content of tree on every postback.

Scenario:
2 users load same tree. First two items are ItemA and ItemB, so, user1 right clicks and deletes ItemA, his view is refreshed and he can see that there is no more ItemA. User2 thinks that he doesn't like ItemA he sees (in his already outdated view), right clicks -> Delete and instead of deleting nonexistent ItemA, ItemB gets deleted, because underneath tree was reloaded in Page_Load and context menu's index remained same, but node changed.

I get referenced node id to delete in
protected void tvProjectElements_ContextMenuItemClick(object sender, RadTreeViewContextMenuEventArgs e) {    }
from e.Node.Value

Suggestion:
Maybe for current (or in general) use case context menus should reference to nodes not by index, but by some internal "node-context menu (item) key"? Or this could be configurable, like setting custom key (most likely same as using custom attributes) or fetch node's DataValueField, anyway, to make them correspond to each other.

Possible workaround:
When I will get back to solving this issue, probably I will give a try to fix this using custom attributes (e.MenuItem.Attributes), setting those in data bound event for each nodes' context menu and checking in ContextMenuItemClick by comparing to e.Node.Value value.

Thanks :)

5 Answers, 1 is accepted

Sort by
0
Plamen
Telerik team
answered on 18 Oct 2011, 04:55 PM
Hello Shukhrat,

That is an interesting observation and suggestion.

I have inspected the ContextMenu demo. Have you considered the chance to validate if the node still exist just before you call the remove method?

Regards,
Plamen Zdravkov
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
0
Shukhrat Nekbaev
Top achievements
Rank 1
answered on 19 Oct 2011, 08:25 AM
Hi,

if I remember correctly e.Node would just reference the item with same index (you will not get reference to "old" item). To know 'who' was old one at that index I need to track it, so that context menu item will tell me to which node it corresponds (this brings us that e.Node is unreliable in that case). When I get back to this I will give a try to context menu's attributes collection, will put there 'real' node Id to which 'exactly this' context menu corresponds to. And when event happens will check that e.Node.Value is equals to context menu's attribute I've set or just use context menu's attribute value to get referenced node. I mean that this is a workaround for e.Node, because context menu references node by index.
0
Plamen
Telerik team
answered on 24 Oct 2011, 09:50 AM
Hello Shukhrat,

I was thinking of some additional custom validation, that can be added by text or attribute as well just before the removing of the node like this:

case "Delete":
                  if (clickedNode.TreeView.FindNodeByText(clickedNode.Text)==null)
                  {
                      clickedNode.Remove();
                  }
                  break;

Hope this will help when you get back to this.

Greetings,
Plamen Zdravkov
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
0
Shukhrat Nekbaev
Top achievements
Rank 1
answered on 01 Nov 2011, 02:18 PM
Hi,

your example will still reference wrong node, I went another way, in Page_Load:
1)using regex I get index of a node that caused context menu postback from __EVENTTARGET (here I check if its a tree that caused the postback) and __EVENTARGUMENT (from this one I get index value)
2)I parse that colon delimited index value and find the node to which it relates
3)I save to int? value of that node
4)Rebind tree

in event handler for ContextMenuItemClick I check:
RadTreeView tree = (RadTreeView) sender;
            RadTreeNode selectedNode;
             
            if (!ProjectContentElementIdSelectedFromContextMenu.HasValue || (selectedNode = tree.FindNodeByValue(ProjectContentElementIdSelectedFromContextMenu.Value.ToString())) == null)
            {
                return;
            }

if this check passes then I get id:
int elementId = Int32.Parse(selectedNode.Value);
and continue with my logic.

That approach verifies if node still exist and if it does context menu operations will be applied to a proper node.
Please note that e.Node can't be used anymore, so use selectedNode.

That's it :)
0
Plamen
Telerik team
answered on 02 Nov 2011, 06:12 PM
Hello Shukhrat,

Thank you for sharing your knowledge with the community.

All the best,
Plamen Zdravkov
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now
Tags
TreeView
Asked by
Shukhrat Nekbaev
Top achievements
Rank 1
Answers by
Plamen
Telerik team
Shukhrat Nekbaev
Top achievements
Rank 1
Share this question
or