Drag & Drop insertion lines on ListView

4 posts, 0 answers
  1. Andrea
    Andrea avatar
    52 posts
    Member since:
    Oct 2012

    Posted 03 Jun Link to this post

    Hello, when using the AllowDragDrop=true on a ListView control, it gives to user a beautiful feedback while doing drag/drop (attached image).

    Since i need to implement drag & drop manually, would be possible to draw insert lines on the listview control in "list" view mode?

    Would be nice to also have the semiopaque cursor while dragging like on the attached image, but that is not that necessary to me.

    The lack of insertion lines in my opinion make not clear for the users where the item will be dropped.

     

    Best Regards

    Andrea

     

  2. Hristo Merdjanov
    Admin
    Hristo Merdjanov avatar
    710 posts

    Posted 08 Jun Link to this post

    Hello Andrea,

    Thank you for writing.

    RadListView provides various means for customizing its drag and drop behavior. By handling the events defined within the ListViewDragDropService you would be able to allow or cancel dragging or dropping of certain items. Additionally, it also provides means for customizing the drag hint and the insertion lines are drawn by default.

    Please refer to the following section of our RadListView documentation: Drag and Drop. I am also sending you a sample project demonstrating how you can access the drag drop service class. In case you would not be able to work with the suggested in the project or documentation approaches, could you please provide me with more details about your scenario and ultimate goal.

    I hope this helps. Should you have further questions please do not hesitate to write back.

    Regards,
    Hristo Merdjanov
    Telerik
    Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms. For more information check out this blog post and share your thoughts.
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Andrea
    Andrea avatar
    52 posts
    Member since:
    Oct 2012

    Posted 08 Jun in reply to Hristo Merdjanov Link to this post

    Thank you for answering,

    But i do not know how to do that properly, maybe you could help me, do not know if i have to open a support ticket for this.

    My application is the following:

    I have a radtreeview, containing a list of nodes, each treenode, references an applicative business object using the Tag property.

    An applicative object could be for example a business relation with another company. a business relation could contain a bunch of contracts, each contract may contain sub contracts, user could create folders that can contain only a specific set of objects depending on its position, for example a folder containing contracts cannot contain  a business relation:

     

    Long story short i need to implement moving items between listview and treeview, and also have to modify the drop icon  so that the user cannot drop an object in the wrong position.

    I attach a working simplified sample, the idea is that the user could move an item into another only if the CanMoveNode function returns true.

    public class Form1 : Form
       {
           public Form1()
           {
               init();
               SomeSampleNode(0, 0, tv.Nodes);
               attachEvents();
           }
     
           RadTreeView tv;
           RadListView lv;
           Random r;
           int next = 0;
     
     
           void attachEvents()
           {
               tv.SelectedNodeChanged += Tv_SelectedNodeChanged; ;
               if (tv.SelectedNode != null)
                   Tv_SelectedNodeChanged(this, new RadTreeViewEventArgs(tv.SelectedNode));
           }
     
           private void Tv_SelectedNodeChanged(object sender, RadTreeViewEventArgs e)
           {
               lv.Items.Clear();
     
               lv.Items.AddRange(
     
                       e.Node.Nodes.Select(a => new ListViewDataItem()
                       {
                           Text = a.Text,
                           Image = a.Image,
                           Tag = a
                       }).ToArray()
                   );
           }
     
           void init()
           {
                tv= new RadTreeView();
               r = new Random();
               tv.Dock = DockStyle.Left;
               tv.Size = new Size(300, 300);
               lv = new RadListView();
               lv.Dock = DockStyle.Fill;
               this.Controls.AddRange(
                   new Control[] {
                        lv,tv
                   }
                   );
     
               Size = new Size(1024, 768);
               this.StartPosition = FormStartPosition.CenterScreen;
                
           }
     
           void SomeSampleNode(int cat, int lev, RadTreeNodeCollection nodes)
           {
               if (lev > 4)
                   return;
               int count = r.Next(1, 4);
               for (int i = 0; i < count; ++i)
               {
                   char c = (char)(cat + 65);
                   string nodeName = c + "_" + (++next);
                   var n = nodes.Add(nodeName);
                   n.Tag = cat;
                   if((r.NextDouble() >= 0.25))
                       SomeSampleNode((r.NextDouble() >= 0.5) ? 1 + cat : 0 + cat, lev+1, n.Nodes);
               }
           }
     
           bool CanMoveNode(object source_tag, object dest_tag)
           {
               int cat1 = (source_tag as int?) ?? -2;
               int cat2 = (dest_tag as int?) ?? -1;
               return cat1 > cat2;
           }
       }

     

     

    So

     

     

     

     

    when the user select a node on the treeview i capture the event.

    The event handler clear the listview and populate it with all the childs on the tree view, each listview item t.

    Now i would like the user be able to move an object from the list to a different node on the tree.

    I should capture the drop event on the treeview.

    Then imagine the user would like to drop a file from its filesystem onto the list, or maybe a csv fragment representing , i now have to capture the drop event on the list (or in the tree) , deserialize the file, and insert it as a new node on the tree (and on the list).

    So what i need is the ability to use the clipboard on drag-drop

  5. Hristo Merdjanov
    Admin
    Hristo Merdjanov avatar
    710 posts

    Posted 10 Jun Link to this post

    Hello Andrea,

    Thank you for writing back.

    The PreviewDragOver event allows you to control on what targets the item being dragged can be dropped on. The PreviewDragDrop event allows you to get a handle on all the aspects of the drag and drop operation, the source (drag) control, the destination (target) control, as well as the item being dragged. Note that if both controls are in bound mode, you should manipulate (add , delete, etc.) the data bound items, not the control's items. Additional information is available here: http://docs.telerik.com/devtools/winforms/listview/drag-and-drop/drag-and-drop-using-raddragdropservice

    Please also check below my code snippet for dragging between RadTreeView and RadListView
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
     
            new RadControlSpyForm().Show();
     
            RadTreeNode node1 = new RadTreeNode("Node1");
            RadTreeNode node2 = new RadTreeNode("Node2");
            RadTreeNode node3 = new RadTreeNode("Node3");
            RadTreeNode node4 = new RadTreeNode("Node4");
            radTreeView1.Nodes.Add(node1);
            radTreeView1.Nodes.Add(node2);
            radTreeView1.Nodes.Add(node3);
            radTreeView1.Nodes.Add(node4);
     
            this.radTreeView1.AllowDragDrop = true;
            this.radListView1.AllowDragDrop = true;
     
            this.radTreeView1.TreeViewElement.DragDropService.PreviewDragOver += DragDropService_PreviewDragOver;
            this.radTreeView1.TreeViewElement.DragDropService.PreviewDragDrop += DragDropService_PreviewDragDrop;
        }
     
        private void DragDropService_PreviewDragDrop(object sender, Telerik.WinControls.RadDropEventArgs e)
        {
            e.Handled = true;
     
            TreeNodeElement draggedItem = e.DragInstance as TreeNodeElement;
            this.radTreeView1.Nodes.Remove(draggedItem.Data);
     
            SimpleListViewElement el = e.HitTarget as SimpleListViewElement;
            if (el != null)
            {
                el.Items.Add(new ListViewDataItem(draggedItem.ContentElement.Text));
            }
     
            SimpleListViewVisualItem hoveredItem = e.HitTarget as SimpleListViewVisualItem;
            if (hoveredItem != null)
            {
                ((SimpleListViewElement)hoveredItem.Parent.Parent).Items.Insert(hoveredItem.Parent.Children.IndexOf(hoveredItem), new ListViewDataItem(draggedItem.ContentElement.Text));
            }
     
        }
     
        private void DragDropService_PreviewDragOver(object sender, Telerik.WinControls.RadDragOverEventArgs e)
        {
            SimpleListViewVisualItem item = e.HitTarget as SimpleListViewVisualItem;
            if (item != null && item.Data.Text.Contains("5"))
            {
                e.CanDrop = false;   
            }
        }
    }

    I hope this helps. Please let me know if you need further assistance.

    Regards,
    Hristo Merdjanov
    Telerik
    Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
Back to Top