This is a migrated thread and some comments may be shown as answers.

Drag & Drop ready to go

22 Answers 511 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Minyie
Top achievements
Rank 1
Minyie asked on 17 May 2011, 11:17 PM
If anyone need it, just use the code and drag and drop :) (Based on example code)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls;
using Telerik.WinControls.UI;
using System.Drawing;
 
namespace Project
{
    public partial class RadDataGridViewDragDrop : RadGridView
    {
        public RadDataGridViewDragDrop()
        {
            InitializeComponent();
            SubscribeForGridEvents();
            this.ReadOnly = true;
            this.MultiSelect = true;
            this.MasterTemplate.AllowRowReorder = true;
            this.GridBehavior = new RadGridViewDragDropBehavior();
        }
 
        private void SubscribeForGridEvents()
        {
            RadDragDropService dragDropService = this.GridViewElement.GetService<RadDragDropService>();
            dragDropService.PreviewDragOver += new EventHandler<RadDragOverEventArgs>(dragDropService_PreviewDragOver);
            dragDropService.PreviewDragDrop += new EventHandler<RadDropEventArgs>(dragDropService_PreviewDragDrop);
            dragDropService.PreviewDragHint += new EventHandler<PreviewDragHintEventArgs>(dragDropService_PreviewDragHint);
        }

        private int GetTargetRowIndex(GridDataRowElement row, Point dropLocation)
        {
            int halfHeight = row.Size.Height / 2;
            int index = row.RowInfo.Index;
            if (dropLocation.Y > halfHeight)
            {
                index++;
            }
            return index;
        }
        private void InitializeRow(GridViewRowInfo destRow, GridViewRowInfo sourceRow)
        {
            foreach (GridViewCellInfo s in sourceRow.Cells)
            {
                destRow.Cells[s.ColumnInfo.Name].Value = s.Value;
            }
        }
        private void MoveRows(RadGridView targetGrid, RadGridView dragGrid, IList<GridViewRowInfo> dragRows, int index)
        {
            for (int i = dragRows.Count - 1; i >= 0; i--)
            {
                GridViewRowInfo row = dragRows[i];
                if (row is GridViewSummaryRowInfo)
                {
                    continue;
                }
                GridViewRowInfo newRow = targetGrid.Rows.NewRow();
                this.InitializeRow(newRow, row);
                targetGrid.Rows.Insert(index, newRow);
                row.IsSelected = false;
                dragGrid.Rows.Remove(row);
                index++;
            }
        }
 
        #region Drag & drop logic
 
        private void dragDropService_PreviewDragDrop(object sender, RadDropEventArgs e)
        {
            GridDataRowElement rowElement = e.DragInstance as GridDataRowElement;
            if (rowElement == null)
            {
                return;
            }
            RadItem dropTarget = e.HitTarget as RadItem;
            RadGridView targetGrid = dropTarget.ElementTree.Control as RadGridView;
            if (targetGrid == null)
            {
                return;
            }
            RadGridView dragGrid = rowElement.ElementTree.Control as RadGridView;
            if (targetGrid != dragGrid)
            {
                e.Handled = true;
                RadGridViewDragDropBehavior behavior = (RadGridViewDragDropBehavior)dragGrid.GridBehavior;
                GridDataRowElement dropTargetRow = dropTarget as GridDataRowElement;
                int index = dropTargetRow != null ? this.GetTargetRowIndex(dropTargetRow, e.DropLocation) : targetGrid.RowCount;
                this.MoveRows(targetGrid, dragGrid, behavior.SelectedRows, index);
            }
        }
 
        private void dragDropService_PreviewDragOver(object sender, RadDragOverEventArgs e)
        {
            if (e.DragInstance is GridDataRowElement)
            {
                e.CanDrop = e.HitTarget is GridDataRowElement || e.HitTarget is GridTableElement || e.HitTarget is GridSummaryRowElement;
            }
        }
 
        private void dragDropService_PreviewDragHint(object sender, PreviewDragHintEventArgs e)
        {
            GridDataRowElement dataRowElement = e.DragInstance as GridDataRowElement;
            if (dataRowElement != null && dataRowElement.ViewTemplate.MasterTemplate.SelectedRows.Count > 1)
            {
                //e.DragHint = new Bitmap(this.imageList1.Images[6]);       
                e.UseDefaultHint = false;
            }
        }
        #endregion
    }
 
    public class RadGridViewDragDropBehavior : BaseGridBehavior
    {
        List<GridViewRowInfo> selectedRows = new List<GridViewRowInfo>();
        public List<GridViewRowInfo> SelectedRows
        {
            get { return this.selectedRows; }
        }
 
        public override bool OnMouseDown(MouseEventArgs e)
        {
            selectedRows.Clear();
            bool result = base.OnMouseDown(e);
            if ((Control.ModifierKeys & Keys.Control) == Keys.Control ||
                (Control.ModifierKeys & Keys.Control) == Keys.Shift)
            {
                selectedRows.AddRange(this.GridControl.SelectedRows);
            }
            else
            {
                selectedRows.Add(this.GridControl.CurrentRow);
            }
            return result;
        }
    }
}

22 Answers, 1 is accepted

Sort by
0
Stefan
Telerik team
answered on 20 May 2011, 02:58 PM
Hi Minyie, thank you for sharing your code with the community. I am sure that someone will benefit from it.
 
Best wishes,
Stefan
the Telerik team
Q1’11 SP1 of RadControls for WinForms is available for download; also available is the Q2'11 Roadmap for Telerik Windows Forms controls.
0
Manesh
Top achievements
Rank 2
answered on 15 Jul 2012, 03:41 PM
Hi, to all,

  The code you posted is been in the demo example and it worked well , but when i implement the exact copy of it then its not allowing me to drag the particular selected row but if i drag the column in to another grid containing the same column then its dragging but only the first row is only dragged........ Y its happening please help me out

code: exactly the copy of the code you posted
0
Stefan
Telerik team
answered on 17 Jul 2012, 12:25 PM
Hi Manesh,

In our latest release we introduced a new highly demanded feature in RadGridView, which allows you to scroll through the grid with its translucent rectangle. This feature however required a small breaking change in the RadGridViewDragDropService. Here is a quote from our Release Notes:
BREAKING CHANGE: The DragInstance for columns and rows of RadGridViewDragDropService is now of type SnapshotDragItem instead of GridRowElement and GridCellElement. The row and column can now be accessed via the GetDataContext method of the DragInstance. 

So, in order to allow the example to work, you need to change the drag and drop logic a bit:
#region Drag & drop logic
 
      private void dragDropService_PreviewDragDrop(object sender, RadDropEventArgs e)
      {
          SnapshotDragItem dragInstance = e.DragInstance as SnapshotDragItem;
          if (dragInstance == null)
          {
              return;
          
 
          RadItem dropTarget = e.HitTarget as RadItem;
          RadGridView targetGrid = dropTarget.ElementTree.Control as RadGridView;
          if (targetGrid == null)
          {
              return;
          }
 
          RadGridView dragGrid = dragInstance.ElementTree.Control as RadGridView;
          if (targetGrid != dragGrid)
          {
              e.Handled = true;
              RadGridViewDragDropBehavior behavior = (RadGridViewDragDropBehavior)dragGrid.GridBehavior;
              GridDataRowElement dropTargetRow = dropTarget as GridDataRowElement;
              int index = dropTargetRow != null ? this.GetTargetRowIndex(dropTargetRow, e.DropLocation) : targetGrid.RowCount;
              this.MoveRows(targetGrid, dragGrid, behavior.SelectedRows, index);
          }
      }
 
      private void dragDropService_PreviewDragOver(object sender, RadDragOverEventArgs e)
      {
          if (e.DragInstance is SnapshotDragItem)
          {
              e.CanDrop = e.HitTarget is GridDataRowElement || e.HitTarget is GridTableElement || e.HitTarget is GridSummaryRowElement;
          }
      }
 
      private void dragDropService_PreviewDragHint(object sender, PreviewDragHintEventArgs e)
      {
          SnapshotDragItem snapShotItem = e.DragInstance as SnapshotDragItem;
          if (snapShotItem == null)
          {
              return;
          }
 
          GridViewRowInfo rowInfo = e.DragInstance.GetDataContext() as GridViewRowInfo;
          if (rowInfo != null && rowInfo.ViewTemplate.MasterTemplate.SelectedRows.Count > 1)
          {
              e.UseDefaultHint = false;
          }
      }
      #endregion

And here is how the custom behavior should look like:
public class RadGridViewDragDropBehavior : BaseGridBehavior
{
    List<GridViewRowInfo> selectedRows = new List<GridViewRowInfo>();
    public List<GridViewRowInfo> SelectedRows
    {
        get { return this.selectedRows; }
    }
 
    public override bool OnMouseDown(MouseEventArgs e)
    {
        selectedRows.Clear();
        bool result = base.OnMouseDown(e);
        if (Control.ModifierKeys  == Keys.Control ||
            Control.ModifierKeys == Keys.Shift)
        {
            selectedRows.AddRange(this.GridControl.SelectedRows);
        }
        else
        {
            selectedRows.Add(this.GridControl.CurrentRow);
        }
        return result;
    }
}

Attached you can find the whole sample implemented.

I hope that you find this information useful.

Regards,
Stefan
the Telerik team
RadControls for WinForms Q2'12 release is now live! Check out what's new or download a free trial >>
0
Manesh
Top achievements
Rank 2
answered on 17 Jul 2012, 05:48 PM
Hi Stefan

I'm using the latest release of the winforms and even i'm un-able to drag a single item if i bind a data source to the grid but its possible to drag single or multiple rows only if we add some sample rows to the grid......... so please how to overcome it.... as i was at the edge of the task please help me
0
Stefan
Telerik team
answered on 19 Jul 2012, 01:41 PM
Hi Manesh,

Drag and drop operation in bound mode is not supported by RadGridView. There is a feature request for such a functionality here: http://www.telerik.com/support/pits.aspx#/details/Issue=11690. Feel free to add your vote for it.

I hope you find this useful.
 
Greetings,
Stefan
the Telerik team
RadControls for WinForms Q2'12 release is now live! Check out what's new or download a free trial >>
0
Pauli
Top achievements
Rank 2
answered on 12 Nov 2012, 02:17 PM
Hi
In example row is moved. I have databound datagrid but I want to just copy data by dragging, so there is no need to reorder or change. How can I do this?

Terveisin
Pauli
0
Stefan
Telerik team
answered on 14 Nov 2012, 11:27 AM
Hello Pauli,

Thank you for writing.

Could you please elaborate a bit more about your scenario:
- Are you going to drag from one grid to another?
- If so, are both grids with the same columns schema?
- Are you going to drag multiple rows?
- Are you going to drag a single row?
- Are you going to drag just a singe cell?

Thank you in advance for your cooperation.

Kind regards,
Stefan
the Telerik team
Q3’12 of RadControls for WinForms is available for download (see what's new). Get it today.
0
Emanuel Varga
Top achievements
Rank 1
answered on 14 Nov 2012, 11:44 AM
Hello,

Pauli, i have a code library project that does drag and drop in bounded mode for grids, currently it supports also reordering but it is easy enough to remove it.

If you need any help on this one, open another thread with your requirements and let me know.

If you have any other questions, please let me know.

Best Regards,
Emanuel Varga
WinForms MVP
0
Pauli
Top achievements
Rank 2
answered on 14 Nov 2012, 01:01 PM
>>>Could you please elaborate a bit more about your scenario:
>>>- Are you going to drag from one grid to another?
I have 2 forms and both have data grid. From grid 1 I want to drag 1-n rows to grid 2. Rows works as an interactive "input" as they are dropped to grid 2. Separate function will insert new rows to grid 2 when it gets "input" from grid 1.

Emanuel thank you very much for your link. I tested it and it looks good. Later I try to use it in my project.

0
Stefan
Telerik team
answered on 19 Nov 2012, 08:01 AM
Hello Pauli,

Let us know if you have any difficulties embedding Emanuel's solution to your project.

All the best,
Stefan
the Telerik team
Q3’12 of RadControls for WinForms is available for download (see what's new). Get it today.
0
Hazarath Reddy
Top achievements
Rank 1
answered on 20 Jul 2015, 09:06 AM
Thank you very much. Its helped me a lot in order to reorder rows 
0
Mark
Top achievements
Rank 2
Bronze
Iron
Veteran
answered on 28 Jul 2016, 07:38 PM

Thanks for the code, it has helped use a lot. But I have a question for you.  We want to be able to enable/disable Drag/Drop operation at the time they chose the row to drag/drop.  For example, if a data element in the row in which you are trying to drag is FALSE, it doesn't allow the drag/drop operation, however, if the data element in the row is TRUE, then we want to allow the drag/drop operation. 

 

TIA for the help.

0
Manesh
Top achievements
Rank 2
answered on 29 Jul 2016, 02:13 AM

Hi Mark,

 

You can set this functionality of enabling and disabling of dragging rows based on a condition after binding the data to the grid and iterating through the rows. and even we can change the color of the un-draggable rows so that the end-user can easily understand the rows he can drag.

 

Regards,

Manesh

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 29 Jul 2016, 11:23 AM
Hello,

Thank you for writing. 

RadGridView handles the whole drag and operation by its RadGridViewDragDropService. The PreviewDragOver event allows you to control on what targets the row being dragged can be dropped on. Hence, if the drop operation is allowed, set the CanDrop property to true. Otherwise, set it to false. The PreviewDragDrop event allows you to get a handle on all the aspects of the drag and drop operation, the source (drag) grid, the destination (target) control, as well as the row being dragged. This is where we will initiate the actual physical move of the row(s) from one grid to the target control. The following help article demonstrates a approach how to handle the drag and drop operation in RadGridView: http://docs.telerik.com/devtools/winforms/gridview/rows/drag-and-drop

I hope this information helps. Should you have further questions I would be glad to help.

Regards,
Dess
Telerik by Progress
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.
0
Mark
Top achievements
Rank 2
Bronze
Iron
Veteran
answered on 11 Aug 2016, 05:22 PM
Ok, how do I prevent the radMessageBox from allowing DROP to happen. If I have the service enabled on my grid and when a user selects an item in the grid, a radMessageBox pops up (because I need it to), the drop affect is there, the user had to drop and then click "YES or NO".  See the attached GIF file. You can see the Drag/Drop thinks it can drop on the radMessageBox form.
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 15 Aug 2016, 10:51 AM
Hello Mark, 

Thank you for writing back. 

When you handle mouse down left, the selection in RadGridView is changed and the drag operation is started. That is why if you show a message box when the selection is changed, you can see the forbidden drop sign. I would recommend you to avoid showing a message box when starting the drag operation because the RadMessageBox is a modal dialog box and it won't allow you to click anything except the dialog box. It would be greatly appreciated if you can provide additional information why do you need to show a message box when the drag operation is started. Once, we have a full understanding of the complete scenario, we can think about a suitable solution and assist you further. Thank you in advance.

If you have any additional questions, please let me know.

Regards,
Dess
Telerik by Progress
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.
0
Mark
Top achievements
Rank 2
Bronze
Iron
Veteran
answered on 15 Aug 2016, 11:39 AM

Since this is a multi user environment and the data the is represented on the grid can change any time by other users or even the same user in another instance of our application, we need to check the state of that record when the user "CLICKS" the record. The attached GIF file in my previous post is just me "CLICKING" on the record, I am not "DRAGGING" it. 

We need a message box because we need to let the user know the status of the selected record and allow them certain actions depending on the status of that record that was selected in the grid.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 16 Aug 2016, 08:10 AM
Hello Mark, 

Thank you for writing back. 

In the following help it is demonstrated how to achieve drag and drop functionality in RadGridView: http://docs.telerik.com/devtools/winforms/gridview/rows/drag-and-drop
In the GridDataRowBehavior.OnMouseDownLeft method the drag drop service is started. I suppose that you use a similar approach. Note that the RadDragDropService.PreviewDragStart event allows you to control when the drag operation to be started. In the code snippet, it is always started. That is why when you click the row, the service is started although you don't perform dragging. I would suggest you to create a derivative of RadGridView and override its OnMouseDown method. Thus, you can show the RadMessageBox and only according to your requirements to allow the drag operation to be started. If the drag operation is not desired at all, just handle the RadDragDropService.PreviewDragStart and set the Cancel property to false
public class CustomGrid : RadGridView
{
    public override string ThemeClassName 
    {
        get
        {
            return typeof(RadGridView).FullName; 
        }
    }
     
    protected override void OnMouseDown(MouseEventArgs e)
    {
        RadGridViewDragDropService svc = this.GridViewElement.GetService<RadDragDropService>() as RadGridViewDragDropService;
        if (svc.State != RadServiceState.Working)
        {
            DialogResult dr = RadMessageBox.Show("Is drag allowed?");
 
            if (dr == DialogResult.OK)
            {
                this.Tag = "CanStartDrag";
            }
        }
        else
        {
            this.Tag = null;
        }
        
        base.OnMouseDown(e);
    }
}

RadDragDropService svc = this.radGridView1.GridViewElement.GetService<RadDragDropService>();
svc.PreviewDragStart += svc_PreviewDragStart;
 
private void svc_PreviewDragStart(object sender, PreviewDragStartEventArgs e)
{
    if (this.radGridView1.Tag == "CanStartDrag")
    {
        e.CanStart = true;
    }
    else
    {
        e.CanStart = true;
    }
}

I hope this information helps. If you have any additional questions, please let me know.

Regards,
Dess
Telerik by Progress
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.
0
Mark
Top achievements
Rank 2
Bronze
Iron
Veteran
answered on 16 Aug 2016, 02:37 PM
This was helpful, but the problem is, that on MouseDown event, the grid's SelectedRow is still on the previous row, which doesn't help me. I need to know, based on row being selected, if the record should prompt the user and then based on the users response allow the drag/drop event to happen.
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 17 Aug 2016, 10:19 AM
Hello Mark, 

Thank you for writing back. 

You can detect which row will be selected considering the mouse down and then show the message. Here is a sample code snippet demonstrating how to get the row to be selected:
 
protected override void OnMouseDown(MouseEventArgs e)
{
    GridDataCellElement cellUnderMouse = this.ElementTree.GetElementAtPoint(e.Location) as GridDataCellElement;
    if (cellUnderMouse !=null)
    {
        Console.WriteLine(cellUnderMouse.Value);
        GridViewDataRowInfo row = cellUnderMouse.RowInfo as GridViewDataRowInfo;
    }
 
//...some other code
 
    base.OnMouseDown(e);
}

I hope this information helps. If you have any additional questions, please let me know.

Regards,
Dess
Telerik by Progress
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.
0
Mark
Top achievements
Rank 2
Bronze
Iron
Veteran
answered on 17 Aug 2016, 01:17 PM
I copied and paste the code above and cllUnderMouse is always NULL.  It never has a value. I am clicking in a cell, so not sure what is going on.
0
Mark
Top achievements
Rank 2
Bronze
Iron
Veteran
answered on 17 Aug 2016, 01:21 PM
Ok, I figured out my issue, it's working now, thanks for the help
Tags
GridView
Asked by
Minyie
Top achievements
Rank 1
Answers by
Stefan
Telerik team
Manesh
Top achievements
Rank 2
Pauli
Top achievements
Rank 2
Emanuel Varga
Top achievements
Rank 1
Hazarath Reddy
Top achievements
Rank 1
Mark
Top achievements
Rank 2
Bronze
Iron
Veteran
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or