Link to home
Start Free TrialLog in
Avatar of ybt
ybt

asked on

C# drag and drop treeview item

In C# I'm trying to implement drag and drop functionality
I used code:

private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            treeView1.Select();
        }

Open in new window


private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
             if (treeView1.SelectedNode.FullPath.Substring(treeView1.SelectedNode.FullPath.Length - 4, 4).ToLower() == ".pdf")
            {

                ls_selected_node = treeView1.SelectedNode.FullPath;
            }
            if(string.IsNullOrEmpty(ls_selected_node) == true)
            {
                MessageBox.Show("Select a valid File.", "Warning",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                return;
            }

            if (e.Button == MouseButtons.Left)
            {

                string file = dirpath1_t + ls_policy_no + "\\" + ls_selected_node;
                string[] files = new string[1];
                files[0] = @file;
                DataObject data = new DataObject(DataFormats.FileDrop, files);
                DoDragDrop(data, DragDropEffects.Copy);
                ls_selected_node = "";
            }
        }

Open in new window


But when I press mouse button on a third level node, I got a root node value and if I use event:

private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
           treeView1.Select();
        }

Open in new window


user has to click twice, first to select and second to drag, how to do it in a right way?
Avatar of it_saige
it_saige
Flag of United States of America image

Here is an example of how to do it:

Form1.cs -
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace EE_Q29135568
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            PopulateTreeView1();
            PopulateTreeView2();
        }

        private string GetImageKey(string fullName, string extension)
        {
            Icon iconForFile = SystemIcons.WinLogo;
            IntPtr hImgSmall;
            SHFILEINFO shinfo = new SHFILEINFO();
            if (string.IsNullOrEmpty(extension))
                extension = "folder";

            if (!imageList1.Images.ContainsKey(extension))
            {
                hImgSmall = NativeMethods.SHGetFileInfo(fullName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), NativeMethods.SHGFI_ICON | NativeMethods.SHGFI_SMALLICON);
                iconForFile = Icon.FromHandle(shinfo.hIcon);
                imageList1.Images.Add(extension, iconForFile);
            }
            return extension;
        }

        private void PopulateTreeView1()
        {
            TreeNode rootNode;

            DirectoryInfo info = new DirectoryInfo(@"../..");
            if (info.Exists)
            {
                rootNode = new TreeNode(info.Name);
                rootNode.Tag = info;
                GetDirectories(info.GetDirectories(), rootNode);
                treeView1.Nodes.Add(rootNode);
            }
        }

        private void PopulateTreeView2()
        {
            TreeNode rootNode;

            DirectoryInfo info = new DirectoryInfo(@"../..");
            if (info.Exists)
            {
                rootNode = new TreeNode(info.Name);
                rootNode.Tag = info;
                GetDirectories(info.GetDirectories(), rootNode);
                treeView2.Nodes.Add(rootNode);
            }
        }

        private void GetDirectories(DirectoryInfo[] parent, TreeNode nodeToAddTo)
        {
            TreeNode aNode;
            DirectoryInfo[] children;
            foreach (DirectoryInfo child in parent)
            {
                aNode = new TreeNode(child.Name, 0, 0);
                aNode.Tag = child;
                aNode.ImageKey = GetImageKey(child.FullName, child.Extension);
                children = child.GetDirectories();
                if (children.Length != 0)
                    GetDirectories(children, aNode);
                nodeToAddTo.Nodes.Add(aNode);
            }
        }

        private void OnDragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }

        private void OnDragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode).FullName, true))
            {
                var tree = sender as TreeView;
                Point point = tree.PointToClient(new Point(e.X, e.Y));
                TreeNode destination = tree.GetNodeAt(point);
                TreeNode data = e.Data.GetData(typeof(TreeNode)) as TreeNode;

                if (!ReferenceEquals(destination, data))
                {
                    destination.Nodes.Add(data.Clone() as TreeNode);
                    destination.Expand();
                    data.Remove();
                }
            }
        }

        private void OnItemDrag(object sender, ItemDragEventArgs e)
        {
            DoDragDrop(e.Item, DragDropEffects.Move);
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SHFILEINFO
    {
        public IntPtr hIcon;
        public int iIcon;
        public uint dwAttributes;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szDisplayName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string szTypeName;
    };

    class NativeMethods
    {
        public const uint SHGFI_ICON = 0x100;
        public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
        public const uint SHGFI_SMALLICON = 0x1; // 'Small icon

        [DllImport("shell32.dll")]
        public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
    }
}

Open in new window

Form1.Designer.cs -
namespace EE_Q29135568
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.splitContainer1 = new System.Windows.Forms.SplitContainer();
            this.treeView1 = new System.Windows.Forms.TreeView();
            this.treeView2 = new System.Windows.Forms.TreeView();
            this.imageList1 = new System.Windows.Forms.ImageList(this.components);
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
            this.splitContainer1.Panel1.SuspendLayout();
            this.splitContainer1.Panel2.SuspendLayout();
            this.splitContainer1.SuspendLayout();
            this.SuspendLayout();
            // 
            // splitContainer1
            // 
            this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.splitContainer1.Location = new System.Drawing.Point(0, 0);
            this.splitContainer1.Name = "splitContainer1";
            // 
            // splitContainer1.Panel1
            // 
            this.splitContainer1.Panel1.Controls.Add(this.treeView1);
            // 
            // splitContainer1.Panel2
            // 
            this.splitContainer1.Panel2.Controls.Add(this.treeView2);
            this.splitContainer1.Size = new System.Drawing.Size(800, 450);
            this.splitContainer1.SplitterDistance = 382;
            this.splitContainer1.TabIndex = 0;
            // 
            // treeView1
            // 
            this.treeView1.AllowDrop = true;
            this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.treeView1.Location = new System.Drawing.Point(0, 0);
            this.treeView1.Name = "treeView1";
            this.treeView1.Size = new System.Drawing.Size(382, 450);
            this.treeView1.TabIndex = 0;
            this.treeView1.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.OnItemDrag);
            this.treeView1.DragDrop += new System.Windows.Forms.DragEventHandler(this.OnDragDrop);
            this.treeView1.DragEnter += new System.Windows.Forms.DragEventHandler(this.OnDragEnter);
            // 
            // treeView2
            // 
            this.treeView2.AllowDrop = true;
            this.treeView2.Dock = System.Windows.Forms.DockStyle.Fill;
            this.treeView2.Location = new System.Drawing.Point(0, 0);
            this.treeView2.Name = "treeView2";
            this.treeView2.Size = new System.Drawing.Size(414, 450);
            this.treeView2.TabIndex = 0;
            this.treeView2.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.OnItemDrag);
            this.treeView2.DragDrop += new System.Windows.Forms.DragEventHandler(this.OnDragDrop);
            this.treeView2.DragEnter += new System.Windows.Forms.DragEventHandler(this.OnDragEnter);
            // 
            // imageList1
            // 
            this.imageList1.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
            this.imageList1.ImageSize = new System.Drawing.Size(16, 16);
            this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.splitContainer1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.splitContainer1.Panel1.ResumeLayout(false);
            this.splitContainer1.Panel2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
            this.splitContainer1.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.SplitContainer splitContainer1;
        private System.Windows.Forms.TreeView treeView1;
        private System.Windows.Forms.TreeView treeView2;
        private System.Windows.Forms.ImageList imageList1;
    }
}

Open in new window

Which produces the following output -User generated imageUser generated image-saige-
Avatar of ybt
ybt

ASKER

You probably did not realize what I need I have a treeview and need to drag pdf item and drop it to outlook email treeview image attached
treeview.JPG
The example solution shows how you can drag node's from one location to another in the same tree and even across tree views.

-saige-
Avatar of ybt

ASKER

In my case this part of code:
aNode.ImageKey = GetImageKey(child.FullName, child.Extension);
                children = child.GetDirectories();
is not working
                children.Length  always 0
Most likely there are not any child directories or you do not have access to them.  You can change the path that the methods look in; in the PopulateTreeView methods, just change the line:
DirectoryInfo info = new DirectoryInfo(@"put whatever path you want here");

Open in new window


-saige-
ASKER CERTIFIED SOLUTION
Avatar of ybt
ybt

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial