This is a migrated thread and some comments may be shown as answers.
Dragging and dropping a row in RadGridView does not work.
7 Answers 27 Views
This is a migrated thread and some comments may be shown as answers.
Eusebio
Top achievements
Rank 1
Veteran
Eusebio asked on 07 Feb 2021, 05:59 PM

Hi there,

I tried dragging and dropping a row into my RadGridView using the "Rows drag & drop" example from the "Progress Telerik UI for WinForms" application but I can't get it to work.

 

My need is to drag only one row and on the same grid.

Please, any suggestions?

Thank you very much.

7 Answers, 1 is accepted

Sort by
0
Eusebio
Top achievements
Rank 1
Veteran
answered on 08 Feb 2021, 10:23 AM

Now I am trying with the example "Windows sdk master" / BoundGridReorderRows.sln but I use DataTable and that example uses objects of an Item class, what would it be like for the DataTable to be used?

Best regards.

 

This is code of BoundGridReorderRows.sln:

        private void MoveRows(RadGridView dragGrid,
            GridViewRowInfo dragRow, int index)
        {
            dragGrid.BeginUpdate();

            GridViewRowInfo row = dragRow;
            if (row is GridViewSummaryRowInfo)
            {
                return;
            }
            if (dragGrid.DataSource != null && typeof(System.Collections.IList).IsAssignableFrom(dragGrid.DataSource.GetType()))
            {
                //bound to a list of objects scenario
                var sourceCollection = (System.Collections.IList)dragGrid.DataSource;
                if (row.Index < index)
                {
                    index--;
                }
                sourceCollection.Remove(row.DataBoundItem);
                sourceCollection.Insert(index, row.DataBoundItem);
            }
            else
            {
                throw new ApplicationException("Unhandled Scenario");
            }

            dragGrid.EndUpdate(true);
        }

 

        public class Item
        {
            public Item(int id, string name)
            {
                this.Id = id;
                this.Name = name;
            }

            public int Id { get; set; }

            public string Name { get; set; }
        }

 

0
Eusebio
Top achievements
Rank 1
Veteran
answered on 08 Feb 2021, 12:33 PM
I also cannot reproduce the "Rows reorder" example.
  Does the fact that Form1 inherits from ExamplesForm have to do with it? We don't have the source code for ExamplesForms.
0
Eusebio
Top achievements
Rank 1
Veteran
answered on 08 Feb 2021, 03:37 PM
I have managed to reproduce the "Rows reorder", but when I use the DataSet linked to the GridView it doesn't work.
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 09 Feb 2021, 08:07 AM
Hello, Eusebio,  

I would recommend you to refer to the following tutorial: https://www.telerik.com/blogs/extending-radgridview-to-enable-row-drag-and-drop-functionality 

At the bottom of the article there is a "DOWNLOAD SOURCE" link from where you can download a complete working project with the drag and drop functionality described in the article.

If you want to get familiar with the RadGridViewDragDropService and how to work with it, you can refer to the following section in our online documentation: https://docs.telerik.com/devtools/winforms/controls/gridview/drag-and-drop/radgridviewdragdropservice 

I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Eusebio
Top achievements
Rank 1
Veteran
answered on 09 Feb 2021, 08:27 AM
Thank you!

This app(https://www.telerik.com/blogs/extending-radgridview-to-enable-row-drag-and-drop-functionality) is made with the DragAndDropRadGrid control.

But my application is using the RadGridView How can I do in this case? Can DragAndDropRadGrid be converted easily?

You do not have code to apply "Rows reorder" (in the same grid).

Thank you very much
0
Eusebio
Top achievements
Rank 1
Veteran
answered on 09 Feb 2021, 10:19 AM
Do you have examples with RadGridViewDragDropService ?
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 09 Feb 2021, 01:49 PM

Hello, Eusebio,  

The previously referred KB article with a complete project actually uses the RadGridViewDragDropService. You have an implementation of the mentioned DragAndDropRadGrid.cs class:

Here is the complete code: 

public class DragAndDropRadGrid : RadGridView
{
        
    public DragAndDropRadGrid() 
    {  
        this.MultiSelect = true;                       
        
        //handle drag and drop events for the grid through the DragDrop service
        RadDragDropService svc = 
                this.GridViewElement.GetService<RadDragDropService>();
        svc.PreviewDragStart += svc_PreviewDragStart;
        svc.PreviewDragDrop += svc_PreviewDragDrop;
        svc.PreviewDragOver += svc_PreviewDragOver;

        //register the custom row selection behavior
        var gridBehavior = this.GridBehavior as BaseGridBehavior;
        gridBehavior.UnregisterBehavior(typeof(GridViewDataRowInfo));
        gridBehavior.RegisterBehavior(typeof(GridViewDataRowInfo),
                                    new RowSelectionGridBehavior());

    }

    //required to initiate drag and drop when grid is in bound mode
    private void svc_PreviewDragStart(object sender, PreviewDragStartEventArgs e)
    {
        e.CanStart = true;
    }

    //gather drag/source grid and target/destination information and initiate 
    //the move of selected rows
    private void svc_PreviewDragDrop(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)
        {
            return;
        }

        var dragGrid = rowElement.ElementTree.Control as RadGridView;
        if (targetGrid != dragGrid)
        {
            e.Handled = true;
            //append dragged rows to the end of the target grid
            int index = targetGrid.RowCount;

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

    private void svc_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 MoveRows(RadGridView targetGrid, RadGridView dragGrid, 
                            IList<GridViewRowInfo> dragRows, int index) 
    { 
        dragGrid.BeginUpdate();
        targetGrid.BeginUpdate();
        for (int i = dragRows.Count - 1; i >= 0; i--)
        {
            GridViewRowInfo row = dragRows[i];
            if (row is GridViewSummaryRowInfo)
            {
                continue;
            }
            if (targetGrid.DataSource == null)
            {
                //unbound scenario
                GridViewRowInfo newRow = targetGrid.Rows.NewRow();

                foreach (GridViewCellInfo cell in row.Cells)
                {
                    if (newRow.Cells[cell.ColumnInfo.Name] != null)
                        newRow.Cells[cell.ColumnInfo.Name].Value = cell.Value;
                }

                targetGrid.Rows.Insert(index, newRow);

                row.IsSelected = false;
                dragGrid.Rows.Remove(row);
            }
            else if (typeof(DataSet).IsAssignableFrom(targetGrid.DataSource.GetType()))
            {
                //bound to a dataset scenario
                var sourceTable = ((DataSet)dragGrid.DataSource).Tables[0];
                var targetTable = ((DataSet)targetGrid.DataSource).Tables[0];

                var newRow = targetTable.NewRow();
                foreach (GridViewCellInfo cell in row.Cells)
                {
                    newRow[cell.ColumnInfo.Name] = cell.Value;
                }

                sourceTable.Rows.Remove(((DataRowView)row.DataBoundItem).Row);
                targetTable.Rows.InsertAt(newRow, index);
            }
            else if (typeof(IList).IsAssignableFrom(targetGrid.DataSource.GetType()))
            {
                //bound to a list of objects scenario
                var targetCollection = (IList)targetGrid.DataSource;
                var sourceCollection = (IList)dragGrid.DataSource;
                sourceCollection.Remove(row.DataBoundItem);
                targetCollection.Add(row.DataBoundItem);
            }
            else
            {
                throw new ApplicationException("Unhandled Scenario");
            }
            index++;
        }
        dragGrid.EndUpdate(true);
        targetGrid.EndUpdate(true);
    }

   
}

//initiates drag and drop service for clicked rows
public class RowSelectionGridBehavior : GridDataRowBehavior
{
    protected override bool OnMouseDownLeft(MouseEventArgs e)
    {
        GridDataRowElement row = this.GetRowAtPoint(e.Location) as GridDataRowElement;
        if (row != null)
        {
            RadGridViewDragDropService svc =
                        this.GridViewElement.GetService<RadGridViewDragDropService>();
            svc.Start(row);
        }
        return base.OnMouseDownLeft(e);
    }
}

This is a derivative of RadGridView, but the separate class is used just as a wrapper to separate the  drag and drop implementation from the code of the form. You can see that all described events for the drag drop service are used here:

If you don't want to separate the logic from the Form.cs file, you can use the default RadGridView, subscribe to the PreviewDragOverPreviewDragDrop events of the service and start the service in the OnMouseDownLeft method of the GridDataRowBehavior.

But I would recommend you to use it as a custom control like in the above example. Thus it would be easier to use it multiple times without duplicating the code.

Should you have further questions please let me know.

Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Asked by
Eusebio
Top achievements
Rank 1
Veteran
Answers by
Eusebio
Top achievements
Rank 1
Veteran
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or