Drop on a RadGridView : getting the targeted row

1 Answer 147 Views
GridView
jacques
Top achievements
Rank 1
jacques asked on 09 Aug 2023, 01:19 PM

Hi,

I'm trying to implement drop of a custom item on a RadGridView, which doesn't come from a telerik control, and I need to get the row where the user has dropped the item.

I have not been able to work with the RadGridViewDragDropService, the events are never fired. Maybe I'm not registering it up correctly...

So I setup a basic winform dragenter + dragdrop events, but in the dragdrop event handler, I'm unable to get the targeted cell or row.

var point = RdgvDestinationFolder.PointToClient(new Point(e.X, e.Y));
var child = RdgvDestinationFolder.GetChildAtPoint(point);
// child is null...

I have researched others topic, and found one with a method "getelementat" but it look like it doesn't exist anymore.

I tried to workaround the issue with caching the RowMouseMove sender... but this event isn't fired when dragging over...

I'm also stuck with 2022.3.1109.40

Thanks for your help.

1 Answer, 1 is accepted

Sort by
0
Accepted
Dess | Tech Support Engineer, Principal
Telerik team
answered on 10 Aug 2023, 01:52 PM

Hello, Jacques,

If I understand your requirement correctly, you need to drag an item from a non-Telerik control and drop it onto the RadGridView. In this cases, the drag and drop operation is entirely managed outside the RadGridViewDragDropService. 

The OLE drag and drop is a suitable functionality for covering drag and drop scenarios between different WinForms controls:

https://learn.microsoft.com/en-us/dotnet/desktop/winforms/advanced/walkthrough-performing-a-drag-and-drop-operation-in-windows-forms?view=netframeworkdesktop-4.8 

The OLE drag and drop is a standard functionality supported by the MS WinForms controls as well as the Telerik controls. However, it seems to be a general programming question and public forums like MSDN and StackOverflow are more suitable for addressing such inquiries.

The RadGridView.ElementTree.GetElementAtPoint method returns what is the element under the mouse considering the passed coordinates.

I have prepared a sample code snippet for your reference which result is illustrated in the below gif file:

        public RadForm1()
        {
            InitializeComponent();

            for (int i = 0; i < 5; i++)
            {
                this.treeView1.Nodes.Add("Item" + i);
            }

            this.radGridView1.Columns.Add("Name");
            this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
            for (int i = 0; i < 5; i++)
            {
                this.radGridView1.Rows.Add(Guid.NewGuid().ToString());
            }

            this.radGridView1.AllowDrop = true;

            this.treeView1.ItemDrag += TreeView1_ItemDrag; 
            this.radGridView1.DragOver += RadGridView1_DragOver;
            this.radGridView1.DragDrop += RadGridView1_DragDrop;
        }

        private void RadGridView1_DragDrop(object sender, DragEventArgs e)
        {
            var targetLocation = this.radGridView1.PointToClient(new Point(e.X, e.Y));
            GridDataCellElement elementUnderMouse = this.radGridView1.ElementTree.GetElementAtPoint(targetLocation) as GridDataCellElement;
            if (elementUnderMouse != null)
            {
                int rowIndex = this.radGridView1.Rows.IndexOf(elementUnderMouse.RowInfo);
                GridViewRowInfo row = this.radGridView1.Rows.NewRow();
                // Retrieve the node that was dragged.  
                TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
                row.Cells["Name"].Value = draggedNode.Text;
                this.radGridView1.Rows.Insert(rowIndex, row);
            }
        }

        private void RadGridView1_DragOver(object sender, DragEventArgs e)
        {
            var targetLocation = this.radGridView1.PointToClient(new Point(e.X, e.Y));
            GridDataCellElement elementUnderMouse = this.radGridView1.ElementTree.GetElementAtPoint(targetLocation) as GridDataCellElement;
            if (elementUnderMouse != null)
            {
                Console.WriteLine(elementUnderMouse);
                e.Effect = e.AllowedEffect;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        } 
        private void TreeView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            // Move the dragged node when the left mouse button is used.  
            if (e.Button == MouseButtons.Left)
            {
                DoDragDrop(e.Item, DragDropEffects.Move);
            }

            // Copy the dragged node when the right mouse button is used.  
            else if (e.Button == MouseButtons.Right)
            {
                DoDragDrop(e.Item, DragDropEffects.Copy);
            }
        } 

        private void TreeView1_MouseDown(object sender, MouseEventArgs e)
        {
            throw new NotImplementedException();
        }

        private void TreeView1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && this.treeView1.SelectedNode != null)
            {
                this.treeView1.DoDragDrop(this.treeView1.SelectedNode.Text, 
                    DragDropEffects.Copy | DragDropEffects.Move);
            }
        }

Note that this is just a sample approach and it may not cover all possible cases. Feel free to further extend it in a way which suits your requirements best.

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

jacques
Top achievements
Rank 1
commented on 14 Aug 2023, 02:39 PM

Hi Dess,

Thank you for the detailed explanation !

I didn't found the grid.ElementTree.GetElementAtPoint() method in the documentation. Thanks for pointing this !

Maybe you could add an article near the radgridviewdragdropservice usage of the gridview documentation ? https://docs.telerik.com/devtools/winforms/controls/gridview/drag-and-drop/radgridviewdragdropservice

Thanks again !

Dess | Tech Support Engineer, Principal
Telerik team
commented on 14 Aug 2023, 02:44 PM

Hi, 

I am glad that the provided example was helpful. I have also created a knowledge base article while working on this case so it may be helpful for other customers as well:

https://docs.telerik.com/devtools/winforms/knowledge-base/drag-node-from-ms-treeview-drop-to-radgridview 

jacques
Top achievements
Rank 1
commented on 14 Aug 2023, 06:01 PM

That's helpful, but maybe too narrowed (ms-treeview) to be found ?

Maybe rename it to a more generic "drag from winform control to radgridview"

In my case I didn't "move" anything to the grid : the data shown in the radgrid are folder targets and my customer wanted to be able to pick pages of a previewed pdf file at one of theses location (by dropping thumbnails). So I didn't want anything to be added to the radgridview I just needed to get the targeted row databound item.

Thanks again.

Dess | Tech Support Engineer, Principal
Telerik team
commented on 15 Aug 2023, 11:05 AM

Happy to hear that the demo project was helpful for achieving your requirement. The provided feedback is greatly appreciated. Hence, we will consider how to include the information in the documentation part as well so more customers can benefit from it.
jacques
Top achievements
Rank 1
commented on 16 Aug 2023, 02:31 PM | edited

Could you propose this suggestion to the dev team ?

If radgridview.GetChildAtPoint(Point p) has no practical use, maybe you could rewrite it to internally call ElementTree.GetElementAtPoint(p)  ?

Regards,

Dess | Tech Support Engineer, Principal
Telerik team
commented on 17 Aug 2023, 05:36 AM

Please have in mind that this method is inherited from the Control class - Control.GetChildAtPoint Method. All RadControls are derivatives of the standard MS Controls. Hence, there is public API that coming by default.
Tags
GridView
Asked by
jacques
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or