.NET TreeView FAQ - Drag and Drop Right Click Menu By Robbe Morris Printer Friendly Version View My Articles
|  |
Working with a Windows Forms .NET TreeView control? This article contains code samples for the most common questions I've recevied. Things such as right click on nodes to show context menues, drag and drop nodes on the same TreeView or even another control, nudge nodes up and down in sibling order, and much more. |
Please download the working sample. It is derived from an old article I did on an alternative approach concerning data binding a DataSet to a TreeView. Download Code
1. Right Click Show Context Menu
private ContextMenu tvSample1Menu = new ContextMenu(); private TreeView tvSample = new TreeView(); private void tvSample_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) {
TreeViewUtil.SetSelectedNodeByPosition(tvSample,e.X,e.Y);
if (tvSample.SelectedNode == null) { return; }
if (e.Button == MouseButtons.Right) { return; }
} private void tvSample_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
switch (e.Button) { case MouseButtons.Right: tvSample1Menu.Show(tvSample,new Point(e.X,e.Y)); break;
default: break; } }
public void SetSelectedNodeByPosition(TreeView tv, int mouseX, int mouseY) { TreeNode node = null;
try {
Point pt = new Point(mouseX,mouseY); tv.PointToClient(pt); node = tv.GetNodeAt(pt);
tv.SelectedNode = node;
if (node == null) return; if (!node.Bounds.Contains(pt)) { return; }
} catch { } return; } 2. Show Context Menu dynamically on selected node. This method uses the placement on screen of the selected node. ContextMenus can be draw by position. Also, you could just as easily programmatically create the ContextMenu versus passing one in like this:
public void ShowContextMenu(TreeView tv,ContextMenu menu) { try { Point pt = new Point(tv.SelectedNode.Bounds.Left, tv.SelectedNode.Bounds.Bottom);
menu.Show(tv,pt); } catch (Exception) { throw; } }
3. Nudge TreeNode Sibling Order Up Or Down
public bool NudgeDown(TreeNode node) {
int newIndex = 0; TreeNode nodeClone = null; try {
if (node == null) { return false; }
newIndex = node.Index + 2;
if (newIndex > node.Parent.Nodes.Count) { return false; }
nodeClone = (TreeNode)node.Clone(); node.Parent.Nodes.Insert(newIndex, nodeClone);
node.Parent.Nodes.Remove(node);
nodeClone.TreeView.SelectedNode = nodeClone;
} catch (Exception) { throw; } return true; }
public bool NudgeUp(TreeNode node) { int newIndex = 0; TreeNode nodeClone = null; try {
if (node == null) { return false; }
if (node.Index == 0) { return false; }
newIndex = node.Index - 1;
nodeClone = (TreeNode)node.Clone();
node.Parent.Nodes.Insert(newIndex, nodeClone);
node.Parent.Nodes.Remove(node);
nodeClone.TreeView.SelectedNode = nodeClone; } catch (Exception) { throw; } return true; }
4. Drag And Drop On Same TreeView or Different Treeview Control. Download the code sample for additional information.
Form Events private void tvSample_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e) { DoDragDrop(e.Item, DragDropEffects.Move); }
private void tvSample_DragEnter(object sender, System.Windows.Forms.DragEventArgs e) { this.DragEnter((TreeView)sender,e); } private void tvSample_DragOver(object sender, System.Windows.Forms.DragEventArgs e) { this.DragOver((TreeView)sender,e); }
private void tvSample_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) { bool dropOnNewControl = false;
try { this.DragDrop((TreeView)sender,e,ref dropOnNewControl);
if (dropOnNewControl) { // Perform action on old and // new control } } catch (Exception err) { Messagebox.Show(err.Message); } }
Resuable methods
public void DragOver(TreeView tv,System.Windows.Forms.DragEventArgs e) {
try {
if (!e.Data.GetDataPresent(NodeObjectName, true)) { return; } Point pt = tv.PointToClient(new Point(e.X,e.Y)); TreeNode tgtnode = tv.GetNodeAt(pt); if (tv.SelectedNode != tgtnode) { tv.SelectedNode = tgtnode; TreeNode drop = (TreeNode)e.Data.GetData(NodeObjectName);
while (tgtnode != null) {
if (tgtnode == drop) { e.Effect = DragDropEffects.None; return; }
tgtnode = tgtnode.Parent; } } e.Effect = DragDropEffects.Move; } catch (Exception) { throw; } }
public void DragDrop(TreeView tv, System.Windows.Forms.DragEventArgs e, ref bool dropOnNewControl) { try {
dropOnNewControl = false;
// Was the target control enabled to accept controls // being dropped on it and was it successful?
if (!e.Data.GetDataPresent(NodeObjectName,true)) { return; } // If not working solely with TreeViews,you'll // to perform a .GetType() on .GetData prior to casting // to a specific object.
TreeNode drop = (TreeNode)e.Data.GetData(NodeObjectName);
TreeNode tgtnode = tv.SelectedNode;
if (drop == drop.TreeView.Nodes[0]) { // the drop node is the root of the tree. // You may not want to permit this. return; }
if (drop == tgtnode) { // Jump out if dropped on self. return; }
if (tgtnode.TreeView == drop.TreeView) { // If same control, act accordingly } else { dropOnNewControl = true; // This is a different control that the node // was dropped on. You may now need to sync up the old object's underlying data. } // This removes the TreeNodes from the TreeView.
drop.Remove();
if (tgtnode == null) { tv.Nodes.Add(drop); } else { tgtnode.Nodes.Add(drop); } drop.EnsureVisible();
tv.SelectedNode = drop; } catch (Exception) { throw; } } |
| Biography |
Robbe is a 2004-2008 Microsoft MVP for C# and the .NET Evangelist for Alinean Inc.. He is also the co-founder of EggHeadCafe. Robbe enjoys scuba diving with the folks at wet-n-fla.
 |
| |
| Article Discussion: TreeView FAQ |
| Robbe Morris posted at 20-Oct-06 10:44 |
 | Original Article |
 |
|
| |
| Storeing datareader value in a Array |
| shams khan replied to Robbe Morris at 17-Nov-06 01:23 |
can any body help me
my question is
i am getting the data from datareader and that values from data reader i want to store in any array
thanks & Regards
khan
|
 |
|
| |
| SetAsSelectedNode |
| Johan Pingree replied to Robbe Morris at 27-Nov-06 04:13 |
Mr. Morris,
How does one set a node as the selected node programmitcally in a Wins Form application on the Treeview control? I have data that I am loading into the form. I allow the user to set a default value on a previous form. That value is a loaded node in the treeview control in the new form they open up. I have already discovered how to expand to the node in the list however I cannot get it to show the node in a "selected" mode/status/state/oriantation, thus even though I am able to show that node and it's siblings expanded in the treeview I have no way of syncranizing it with the data that is loaded. IMHO there seems to be a property that is missing from this control: like SetAsSelectedNode.. |
 |
|
| |
| Read the code sample more closely |
| Robbe Morris replied to Johan Pingree at 27-Nov-06 04:16 |
 | The to set the treeView.SelectedNode object is in there. |
 |
|
| |
| Ok found it and thank you |
| Johan Pingree replied to Robbe Morris at 27-Nov-06 06:29 |
thanks I should have looked at your code first. |
 |
|
| |
| How to do these thing in a web form ? |
| suman das replied to Robbe Morris at 24-Jan-07 06:35 |
I want this to happen in asp.net web form .how to do this ...please help.
best regards
suman |
 |
|
| |
| Treeview ContextMenu.. |
| DotNetKanna . replied to Robbe Morris at 20-Jul-07 01:58 |
Mr Morris,
Im getting the error in TreeViewUtil The error is the name TreeViewUtil does not exixt in the current context...What i have to do..do i want to refer any namespaces?
Regards
Kanna |
 |
|