I have a subclass of System.Windows.Forms.TreeView that's manually "bound" to a set of hierarchical data. I want the user to be able to edit the labels of the tree, and have the changes reflected back to the data. So I set LabelEdit to true and overrode OnAfterLabelEdit to the tune of:
protected override void OnAfterLabelEdit(NodeLabelEditEventArgs e)
{
base.OnAfterLabelEdit(e);
TreeNode node = e.Node;
if (PassesSomeValidation(e.Label))
{
MyDataNode dataNode = node.Tag as MyDataNode;
dataNode.SomeBoundValue = e.Label;
int oldIndex = node.Index;
int newIndex = RepositionChangedDataNode(dataNode);
TreeNode parent = node.Parent;
parent.Nodes.RemoveAt(oldIndex);
parent.Nodes.Insert(newIndex, node);
}
else
{
e.CancelEdit = true;
}
}
RepositionChangedDataNode() re-sorts the data and returns the index into which the change node moved after sorting. I was hoping I could simply move the edited node to reflect this move.
The problem is that this causes the node to stay in edit mode! I've tried calling EndEdit(), cloning the node before inserting it, setting LabelEdit to false and back to true, wrapping the change in BeginUpdate()/EndUpdate(), and various combinations of these ideas, but none of them have any effect.
The culprit seems to be the insertion. Even if I attempt to insert a totally new node, it will go into edit mode immediately.
So, is there any way to make TreeView not behave this way? And if not, is there a good workaround?
Some ideas I've considered:
- Set a custom TreeViewNodeSorter. Would prefer not to have to sort my data twice, though.
- Set a flag and delay the remove-insert step until some point after AfterLabelEdit. It works to do it during WndProc, but this feels like a big kludge that is likely to fail somehow.
Use
BeginInvoke()to push the remove-insert step back onto the message queue like so:BeginInvoke(new MethodInvoker(delegate( { parent.Nodes.RemoveAt(oldIndex); parent.Nodes.Insert(newIndex, node); }));This works and seems cleaner to me than #2, but I know this is probably not how
BeginInvoke()was intended to be used, and that it may have repercussions that my very limited knowledge of the message pump cannot predict.