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
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
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
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
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
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
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
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
>>>- 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.
Let us know if you have any difficulties embedding Emanuel's solution to your project.
All the best,
Stefan
the Telerik team
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.
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
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
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
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.
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
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