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

Drag & Drop multiple rows for GridView

12 Answers 510 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Bala
Top achievements
Rank 1
Bala asked on 05 Jul 2013, 09:25 PM
I have two GridViews: radGridView1, radGridViewPreview
I want drag items from radGridView1 and drop to radGridViewPreview
also do the same drag & drop items within radGridViewPreview
I am able to drag & drop one item from one GridView to the other or within the same GridView with the following code.
However, I am not able to get multiple-rows drag & drop work. Please help. thanks
void initialize()   //this is
{

SetupDragDrop(radGridViewPreview);

SetupDragDrop(radGridView1);

}
        private void SetupDragDrop(RadGridView grid)
        {
            grid.MultiSelect = true;
            //handle drag and drop events for the grid through the DragDrop service
            var svc = grid.GridViewElement.GetService<RadDragDropService>();
            svc.PreviewDragStart += svc_PreviewDragStart;
            svc.PreviewDragDrop += SvcPreviewDragDrop;
            svc.PreviewDragOver += svc_PreviewDragOver;
            //register the custom row selection behavior
            grid.GridBehavior = new CustomGridBehavior();
        }

        private void svc_PreviewDragStart(object sender, PreviewDragStartEventArgs e)
        {
            e.CanStart = true;
        }
 
        private void SvcPreviewDragDrop(object sender, RadDropEventArgs e)
        {
            var rowElement = e.DragInstance as GridDataRowElement;

            if (rowElement == null)
            {
                return;
            }
            e.Handled = true;

            var dropTarget = e.HitTarget as RadItem;
            var targetGrid = dropTarget.ElementTree.Control as RadGridView;
            if (targetGrid == null || targetGrid == radGridView1)
            {
                return;
            }

            var dragGrid = rowElement.ElementTree.Control as RadGridView;

            //Grab every selected row from the source grid, including the current row
            List<GridViewRowInfo> dragRows = dragGrid.SelectedRows.ToList<GridViewRowInfo>();
            if (dragGrid.CurrentRow != null)
            {
                GridViewRowInfo row = dragGrid.CurrentRow;
                if (!dragRows.Contains(row)) dragRows.Add(row);
            }

            var dropTargetRow = dropTarget as GridDataRowElement;
            int indexToMoveTo = targetGrid.RowCount;
            if (dropTargetRow != null) indexToMoveTo = GetTargetRowIndex(dropTargetRow, e.DropLocation);
            if (targetGrid != dragGrid)
            {
                e.Handled = true;
                MoveRows(targetGrid, dragGrid, dragRows, indexToMoveTo);
            }
            else
            {
                MoveRowsWithinGrid(targetGrid, dragRows, indexToMoveTo);
            }
        }
  
  private void svc_PreviewDragOver(object sender, RadDragOverEventArgs e)
        {
            if (e.DragInstance is GridDataRowElement || e.DragInstance is ListViewDataItem)
            {
                e.CanDrop = e.HitTarget is GridDataRowElement || e.HitTarget is GridTableElement || e.HitTarget is GridSummaryRowElement;
            }
        }
  
 public class CustomGridBehavior : BaseGridBehavior
    {
        List<GridViewRowInfo> selectedRows = new List<GridViewRowInfo>();

        public List<GridViewRowInfo> SelectedRows
        {
            get { return selectedRows; }
        }

        public override bool OnMouseDown(MouseEventArgs e)
        {
            selectedRows.Clear();
            bool result = base.OnMouseDown(e);
   selectedRows.AddRange(this.GridControl.SelectedRows);
            return result;
        }
    }

 

 

 

 

12 Answers, 1 is accepted

Sort by
0
Accepted
George
Telerik team
answered on 09 Jul 2013, 02:33 PM
Hi Bala,

Thank you for writing.

I am attaching a sample project which demonstrates a drag-drop behavior. It is similar to your example, with some small changes. You can select rows with the Ctrl or Shift keys and then just drag-drop them.

I hope this helps.
 
Regards,
George
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Bala
Top achievements
Rank 1
answered on 09 Jul 2013, 03:54 PM
Great! This solved my issue

Thanks a lot!
0
Bala
Top achievements
Rank 1
answered on 09 Jul 2013, 08:10 PM
Another question
When I drag multiple items, during dragging, there is only one item displayed.
How to display all the drag items under cursor during drag process?

Thanks 
0
Bala
Top achievements
Rank 1
answered on 10 Jul 2013, 09:08 PM
I use the following code, add an event handler to PreviewDragHint 
It is working though not perfect, i.e. not exactly same as the default one 
The image displayed not starting from the mouse pointer.  I tried to but could not. 

Thanks

        void SvcPreviewDragHint(object sender, PreviewDragHintEventArgs e)
        {
            var dataRowElement = e.DragInstance as GridDataRowElement;
            if (dataRowElement != null)
            {
                var control = dataRowElement.ElementTree.Control;
                Bitmap itemBitmap;
                if (control == radGridView1)
                {
                    itemBitmap = GetBitmap(radGridView1);
                }
                else
                {
                    itemBitmap = GetBitmap(radGridViewPreview);
                }
                e.DragHint = itemBitmap;
                e.UseDefaultHint = false;
            }
        }

        /// <summary>
        ///     Creates the actual bitmap 
        /// </summary>
        /// <param name="grid">grid as type MyGrid</param>
        /// <returns>Returns a Bitmap</returns>
        private static Bitmap GetBitmap(RadGridView grid)
        {
            var size = Size.Empty;
            for (var i = 0; i < grid.SelectedRows.Count; i++)
            {
                GridRowElement rowElement = grid.TableElement.GetRowElement(grid.SelectedRows[i]);
                if (rowElement != null)
                {
                    size.Height += grid.SelectedRows[i].GetActualHeight(rowElement.TableElement);
                }
            }
            size.Width = grid.GridElement.VisualRows[0].ControlBoundingRectangle.Width;
            if (size.Height == 0) { size.Height = grid.GridElement.VisualRows[0].ControlBoundingRectangle.Height; }
            int x = size.Width / 2;
            var bitmap = new Bitmap(size.Width + x, size.Height);
            using (var g = Graphics.FromImage(bitmap))
            {
                for (int i = 0, y = 0; i < grid.SelectedRows.Count; i++)
                {
                    GridRowElement row = grid.TableElement.GetRowElement(grid.SelectedRows[i]);
                    if (row == null) continue;
                    using (var bmp = row.GetAsBitmap(Brushes.White, 0, new SizeF(1, 1)))
                    {
                        g.DrawImage(bmp, x, y);
                        y += row.ControlBoundingRectangle.Height;
                    }
                }
            }
            return bitmap;
        }
0
George
Telerik team
answered on 11 Jul 2013, 01:53 PM
Hi Bala,

Thank you for writing.

I reviewed your code and discovered that the following cast is always null 
var dataRowElement = e.DragInstance as GridDataRowElement;

You should change it to this
var dataRowElement = e.DragInstance as SnapshotDragItem;

I am also attaching a picture which shows how it is working on my side.

I hope this helps.
 
Regards,
George
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
hesam
Top achievements
Rank 1
answered on 03 Jan 2015, 07:25 AM
Hi George, thank you for your answer
i used your solution and it work really well, but I don't know why resizing behavior of the grid no longer working well,
can you help me with this?
0
hesam
Top achievements
Rank 1
answered on 03 Jan 2015, 07:52 AM
I mean Column resizing of course
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 07 Jan 2015, 03:53 PM
Hello Hesam,

Thank you for writing.

The problem with column resizing occurred because of the custom BaseGridBehavior which performs the base MouseDown logic in the MouseUp event. I would recommend you to have a look at our GridView >> Rows >> Drag and Drop help article which demonstrates a sample approach for achieving drag and drop functionality between two RadGridView controls. It is not supposed to experience any issues with column resizing.

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

Regards,
Desislava
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
QuZhi
Top achievements
Rank 1
answered on 16 Aug 2017, 09:45 AM
I had tried the demo by your post, it work. But I have found a problem:With the drag-drop behavior click the colume header will trigger the drag-drop by mistake. Can this be avoided?
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 16 Aug 2017, 10:56 AM
Hello, 

Thank you for writing.  

In RadGridViewDragDropService.PreviewDragStart event you can control whether the drag and drop operation will be started. Here is a sample code snippet demonstrating how to prevent starting the drag operation for the header cells:
private void svc_PreviewDragStart(object sender, PreviewDragStartEventArgs e)
{
    SnapshotDragItem draggedItem = e.DragInstance as SnapshotDragItem;
    if (draggedItem != null)
    {
        GridHeaderCellElement headerCell = draggedItem.Item as GridHeaderCellElement;
        if (headerCell != null)
        {
            e.CanStart = false;
        }
        else
        {
            e.CanStart = true;
        }
    }
    else
    {
        e.CanStart = true;
    }
}

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

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
QuZhi
Top achievements
Rank 1
answered on 16 Aug 2017, 12:53 PM

I have try to use the demo code from document and add the multi selections.

Also mix the drag preview of multi selecting from Bala.

Hope can help other people.

PS:The code need the complete project from George`s demo.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 17 Aug 2017, 07:16 AM
Hello, 

Thank you for writing back. 

By default, the drag and drop operation should be allowed for the header cells. It allows columns reordering. That is why it should be stopped explicitly in the RadGridViewDragDropService.PreviewDragStart event.

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

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
GridView
Asked by
Bala
Top achievements
Rank 1
Answers by
George
Telerik team
Bala
Top achievements
Rank 1
hesam
Top achievements
Rank 1
Dess | Tech Support Engineer, Principal
Telerik team
QuZhi
Top achievements
Rank 1
Share this question
or