someone can tell me how to drag and drop data between gridcontrol and schedulercontrol from devexpress? I want to drag the data from the grid and drop it on the scheduler. The devexpress example in the demo doesnt work for me. I just get a block-symbol.
regards
I got it.
private void grdGrid_MouseDown(object sender, MouseEventArgs e)
{
posImGrid = null;
GridHitInfo hitInfo = grvView.CalcHitInfo(new Point(e.X, e.Y));
if (Control.ModifierKeys != Keys.None)
{
return;
}
if ((e.Button == System.Windows.Forms.MouseButtons.Left) &&
(hitInfo.InRow) &&
(hitInfo.HitTest != GridHitTest.RowIndicator))
{
posImGrid = hitInfo;
}
}
private void grdGrid_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button == System.Windows.Forms.MouseButtons.Left) &&
(posImGrid != null))
{
Size dragSize = SystemInformation.DragSize;
Rectangle dragRect = new Rectangle(new Point(posImGrid.HitPoint.X - dragSize.Width / 2,
posImGrid.HitPoint.Y - dragSize.Height / 2), dragSize);
if (!dragRect.Contains(new Point(e.X, e.Y)))
{
grvView.GridControl.DoDragDrop(GetDragData(grvView), DragDropEffects.All);
posImGrid = null;
}
}
}
private SchedulerDragData GetDragData(GridView view)
{
Appointment termin = Storage.CreateAppointment(AppointmentType.Normal);
clsMeineKlasse tempObjekt = (clsMeineKlasse)grvView.GetFocusedRow();
termin.Description = tempObjekt.Beschreibung;
termin.Subject = tempObjekt.Bezeichnung;
termin.Duration = TimeSpan.FromHours(8);
SchedulerDragData sdd = new SchedulerDragData(termin);
return sdd;
}
Related
An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code
Additional Information : Rows cannot be programmatically removed unless the DataGridView is data-bound to an IBindingList that supports change notification and allows delete
This is how I bind my data to datagridview :
IEnumerable<myTable> query = from p in db.myTables select p;
testList = query.ToList();
dataGridView1.DataSource = testList;
And this is what I use to drag & drop rows :
private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
{
if (dataGridView1.SelectedRows.Count == 1)
{
if (e.Button == MouseButtons.Left)
{
rw = dataGridView1.SelectedRows[0];
rowIndexFromMouseDown = dataGridView1.SelectedRows[0].Index;
dataGridView1.DoDragDrop(rw, DragDropEffects.Move);
}
}
}
private void dataGridView1_DragEnter(object sender, DragEventArgs e)
{
if (dataGridView1.SelectedRows.Count > 0)
{
e.Effect = DragDropEffects.Move;
}
}
private void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
int rowIndexOfItemUnderMouseToDrop;
Point clientPoint = dataGridView1.PointToClient(new Point(e.X, e.Y));
rowIndexOfItemUnderMouseToDrop = dataGridView1.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
if (e.Effect == DragDropEffects.Move)
{
dataGridView1.Rows.RemoveAt(rowIndexFromMouseDown);
dataGridView1.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rw);
}
}
Whenever I tried to drag & drop, dragging is ok but drop causes the error that I mentioned above, and if possible I dont want to use bindinglist because if I use it I will have to make lots of changes.
If you can help I would be greateful.
I fixed the problem. I've made changes on mouse events
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(e.X, e.Y))
{
DragDropEffects dropEffect = dataGridView1.DoDragDrop(dataGridView1.Rows[rowIndexFromMouseDown], DragDropEffects.Copy);
}
}
}
private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
// Get the index of the item the mouse is below.
rowIndexFromMouseDown = dataGridView1.HitTest(e.X, e.Y).RowIndex;
if (rowIndexFromMouseDown != -1)
{
Size dragSize = SystemInformation.DragSize;
dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
}
else
dragBoxFromMouseDown = Rectangle.Empty;
}
private void dataGridView1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
try
{
if (e.Data.GetDataPresent(typeof(DataGridViewRow)))
{
Point clientPoint = dataGridView1.PointToClient(new Point(e.X, e.Y));
if (e.Effect == DragDropEffects.Copy)
{
DataGridViewRow Row = (DataGridViewRow)e.Data.GetData(typeof(DataGridViewRow));
dataGridView1.Rows.Add(Row.Cells[0].Value, Row.Cells[1].Value, Row.Cells[2].Value);
}
}
else
{
//Reflect the exception to screen
MessageBox.Show("Geen data! #01", "Error");
}
}
catch (Exception msg)
{
MessageBox.Show(msg.Message, "Error");
}
}
So i have a main form then multiple windows with data grid views in.
I want to be able to swap data to and from the main window to the child windows and vice versa.
I have on my main form:
private Rectangle dragBoxFromMouseDown;
private object valueFromMouseDown;
private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
var hittestInfo = dataGridView1.HitTest(e.X, e.Y);
if (hittestInfo.RowIndex != -1 && hittestInfo.ColumnIndex != -1)
{
valueFromMouseDown = dataGridView1.Rows[hittestInfo.RowIndex];
if (valueFromMouseDown != null)
{
Size dragSize = SystemInformation.DragSize;
dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
}
}
else
dragBoxFromMouseDown = Rectangle.Empty;
}
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(e.X, e.Y))
{
DragDropEffects dropEffect = dataGridView1.DoDragDrop(valueFromMouseDown, DragDropEffects.Copy);
}
}
}
Then on my child forms:
private void dataGridView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void dataGridView1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
private void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
Point clientPoint = dataGridView1.PointToClient(new Point(e.X, e.Y));
DataGridView.HitTestInfo hit = dataGridView1.HitTest(clientPoint.X, clientPoint.Y);
if (hit.RowIndex != -1)
{
dataGridView1.Rows.Insert(hit.RowIndex, e.Data.GetData(typeof(Objects.Amazon.PoDetail)));
}
else
{
dataGridView1.Rows.Add(e.Data.GetData(typeof(Objects.Amazon.PoDetail)));
}
}
Obviously, it fails at the e.Data.GetData as its getting the data from the current datagridview in the child form.
I can't think of a way of passing the data between the forms.
How that can be possible. dragdrop data is of same type you have passed in DoDragDrop method. thus it is of DataGridViewRow type. So that should be-
object dropData = e.Data.GetData(typeof(DataGridViewRow));
I'm trying to allow my users to swap two DevExpress chart controls (although I believe pretty much any control should work...), by dragging one over the top of the other. I have done this for my TabControl (to allow swapping/moving of tabs), but for some reason I appear to be missing something here which is stopping me doing the same with my ChartControl.
It "should" draw a grey-ish box over the chartcontrol and allow the user to drag it to wherever they like, but I just get a black circle with a stripe through it.
Here is the code I have written so far, hopefully one of you will be able to spot the mistake and I can stop pulling my hair out! :)
private void ChartControlMouseMove(object sender, MouseEventArgs e)
{
// Handle Mouse move only if left button is pressed.
if (e.Button == MouseButtons.Left)
{
var chartControl = (ChartControl)sender;
// If the mouse moves outside the rectangle, start the drag.
if (!rectDragBoxFromMouseDown.Equals(Rectangle.Empty)
& !rectDragBoxFromMouseDown.Contains(e.X, e.Y))
{
Invalidate();
DoDragDrop(chartControl, DragDropEffects.Move);
CalcRectDragBox(e.X, e.Y);
Invalidate();
}
}
}
private void ChartControlMouseDown(object sender, MouseEventArgs e)
{
CalcRectDragBox(e.X, e.Y);
}
private void CalcRectDragBox(int x, int y)
{
// Remember the point where the mouse down occurred. The DragSize indicates
// the size that the mouse can move before a drag event should be started.
var dragSize = SystemInformation.DragSize;
// Create a rectangle using the DragSize, with the mouse position being
// at the center of the rectangle.
rectDragBoxFromMouseDown = new Rectangle(
new Point(x - (dragSize.Width/2), y - (dragSize.Height/2)), dragSize);
}
private void ChartControlDragOver(object sender, DragEventArgs e)
{
var chartControl = (ChartControl)sender;
// get the control we are hovering over.
var hitInformation = chartControl.CalcHitInfo(chartControl.PointToClient(new Point(e.X, e.Y)));
if ((hitInformation != null))
{
//ChartHitInfo hoverTab = hitInformation;
if (e.Data.GetDataPresent(typeof(ChartControl)))
{
e.Effect = DragDropEffects.Move;
var dragTab = (ChartControl)e.Data.GetData(typeof(ChartControl));
if (dragTab != chartControl)
{
for (int i = 0; i < layoutControlGroupDashboard.Items.Count; i++)
{
var layoutControlItem = layoutControlGroupDashboard.Items[i] as LayoutControlItem;
if (layoutControlItem != null && layoutControlItem.Control == chartControl)
{
for (int j = 0; j < layoutControlGroupDashboard.Items.Count; j++)
{
var controlItem = layoutControlGroupDashboard.Items[j] as LayoutControlItem;
if (controlItem != null && controlItem.Control == dragTab)
{
if (!_ignoreNextDrag)
{
_ignoreNextDrag = true;
layoutControlGroupDashboard.BeginInit();
var layoutControlItemi = layoutControlGroupDashboard.Items[i] as LayoutControlItem;
if (layoutControlItemi != null)
{
Control tempControlI =
layoutControlItemi.Control;
var layoutControlItemj = layoutControlGroupDashboard.Items[j] as LayoutControlItem;
if (layoutControlItemj != null)
{
layoutControlItemi.BeginInit();
layoutControlItemj.BeginInit();
Control tempControlJ =
layoutControlItemj.Control;
layoutControlItemi.Control =
null;
layoutControlItemj.Control =
null;
layoutControlItemi.Control =
tempControlJ;
layoutControlItemj.Control =
tempControlI;
layoutControlItemi.EndInit();
layoutControlItemj.EndInit();
}
}
layoutControlGroupDashboard.EndInit();
break;
}
else
{
_ignoreNextDrag = false;
break;
}
}
}
}
}
}
}
}
else
{
e.Effect = DragDropEffects.None;
}
}
Again, the idea is to allow the user to swap the controls around just click click-dragging things around... Hopefully it's just something simple I'm missing, but I can't see it for the life of me!
Edit: This is something I tried (adding my chart to a panel first...)
Panel panel = new Panel();
panel.Name = Guid.NewGuid().ToString();
panel.Controls.Add(chartControl);
var dashboardItem = new LayoutControlItem(layoutControlDashboard, panel)
{
Padding = new DevExpress.XtraLayout.Utils.Padding(0),
Spacing = new DevExpress.XtraLayout.Utils.Padding(0),
SizeConstraintsType = SizeConstraintsType.Custom
};
Here is the modified ChartControlDragOver method which work in case the ChartControl is placed in the LayoutControl:
private void ChartControlDragOver(object sender, DragEventArgs e) {
var chartControl = (ChartControl)sender;
// get the control we are hovering over.
var hitInformation = chartControl.CalcHitInfo(chartControl.PointToClient(new Point(e.X, e.Y)));
if ((hitInformation != null)) {
//ChartHitInfo hoverTab = hitInformation;
if (e.Data.GetDataPresent(typeof(ChartControl))) {
e.Effect = DragDropEffects.Move;
var dragTab = (ChartControl)e.Data.GetData(typeof(ChartControl));
if (dragTab == chartControl) return;
InsertType insertType = InsertType.Left;
Point hitPoint = chartControl.Parent.PointToClient(new Point(e.X, e.Y));
if (dragTab.Bounds.Left < hitPoint.X && dragTab.Bounds.Right > hitPoint.X) {
if (dragTab.Bounds.Top > hitPoint.Y)
insertType = InsertType.Top;
else if (dragTab.Bounds.Bottom < hitPoint.Y)
insertType = InsertType.Bottom;
} else if (dragTab.Bounds.Right < hitPoint.X)
insertType = InsertType.Right;
else if (dragTab.Bounds.Left > hitPoint.X)
insertType = InsertType.Left;
LayoutControl layout = (LayoutControl)chartControl.Parent;
layout.GetItemByControl(dragTab).Move(layout.GetItemByControl(chartControl), insertType);
}
} else {
e.Effect = DragDropEffects.None;
}
}
As the title really - I have some code for reordering some thumbnails in a ListView ('LargeIcon' view format), and it works great when dragging an image to the right (i.e. a greater index). But when dragging to the left it doesn't work at all.
Any ideas?
private void lstImages_ItemDrag(object sender, ItemDragEventArgs e)
{
lstImages.DoDragDrop(lstImages.SelectedItems, DragDropEffects.Move);
}
private void lstImages_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection)))
{
e.Effect = DragDropEffects.Move;
}
}
private void lstImages_DragDrop(object sender, DragEventArgs e)
{
if (lstImages.SelectedItems.Count == 0) return;
Point p = lstImages.PointToClient(new Point(e.X, e.Y));
ListViewItem dragToItem = lstImages.GetItemAt(p.X, p.Y);
if (dragToItem == null) return;
int dragIndex = dragToItem.Index;
ListViewItem dataItem = (e.Data.GetData(typeof(ListView.SelectedListViewItemCollection)) as ListView.SelectedListViewItemCollection)[0];
int itemIndex = dragIndex;
if (itemIndex == dataItem.Index) return;
itemIndex = itemIndex + 1;
ListViewItem insertItem = (ListViewItem)dataItem.Clone();
lstImages.Items.Insert(itemIndex, insertItem);
lstImages.Items.Remove(dataItem);
}
I modified your code a little bit and it works now. (Just the _DragDrop part). There seems to be a bug and it can be fixed by changing the alignment during Drag & Drop.
listView1.Alignment = ListViewAlignment.Default;
if (listView1.SelectedItems.Count == 0)
return;
Point p = listView1.PointToClient(new Point(e.X, e.Y));
ListViewItem MovetoNewPosition = listView1.GetItemAt(p.X, p.Y);
if (MovetoNewPosition == null) return;
ListViewItem DropToNewPosition = (e.Data.GetData(typeof(ListView.SelectedListViewItemCollection)) as ListView.SelectedListViewItemCollection)[0];
ListViewItem CloneToNew = (ListViewItem)DropToNewPosition.Clone();
int index = MovetoNewPosition.Index;
listView1.Items.Remove(DropToNewPosition);
listView1.Items.Insert(index, CloneToNew);
listView1.Alignment = ListViewAlignment.SnapToGrid;
I'm attempting to write some code to allow the users of my application to drag and drop rows in a DataGridView to reorder them. The problem is, the row that is being dragged disappears when it's dropped - so dragging and dropping has the effect of just removing that row. Here is my code:
private Rectangle dragBoxFromMouseDown;
private int rowIndexFromMouseDown;
private int rowIndexOfItemUnderMouseToDrop;
private void grdCons_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(e.X, e.Y))
{
DragDropEffects dropEffect = grdCons.DoDragDrop(grdCons.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
}
}
}
private void grdCons_MouseDown(object sender, MouseEventArgs e)
{
rowIndexFromMouseDown = grdCons.HitTest(e.X, e.Y).RowIndex;
if (rowIndexFromMouseDown != -1)
{
Size dragSize = SystemInformation.DragSize;
dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize);
}
else
{
dragBoxFromMouseDown = Rectangle.Empty;
}
}
private void grdCons_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void grdCons_DragDrop(object sender, DragEventArgs e)
{
Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
rowIndexOfItemUnderMouseToDrop = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
if (e.Effect == DragDropEffects.Move)
{
DataGridViewRow rowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
grdCons.Rows.RemoveAt(rowIndexFromMouseDown);
grdCons.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);
}
}
At a guess, the Insert on the DGV on the DragDrop event isn't working.
Here is a cleaned up version of your code that works:
public Form1()
{
InitializeComponent();
grdCons.Rows.Add(7);
for (int i = 0; i < grdCons.Rows.Count; i++)
{
grdCons.Rows[i].Cells[0].Value = i;
grdCons.Rows[i].Cells[1].Value = "Cell " + i;
}
grdCons.AllowDrop = true;
grdCons.AllowUserToAddRows = false;
grdCons.AllowUserToDeleteRows = false;
grdCons.MouseMove += new MouseEventHandler(grdCons_MouseMove);
grdCons.MouseDown += new MouseEventHandler(grdCons_MouseDown);
grdCons.DragOver += new DragEventHandler(grdCons_DragOver);
grdCons.DragDrop += new DragEventHandler(grdCons_DragDrop);
}
private int rowIndexFromMouseDown;
private void grdCons_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
grdCons.DoDragDrop(grdCons.Rows[rowIndexFromMouseDown], DragDropEffects.Move);
}
}
private void grdCons_MouseDown(object sender, MouseEventArgs e)
{
rowIndexFromMouseDown = grdCons.HitTest(e.X, e.Y).RowIndex;
}
private void grdCons_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void grdCons_DragDrop(object sender, DragEventArgs e)
{
Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
int targetIndex = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
if (e.Effect == DragDropEffects.Move)
{
DataGridViewRow rowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
grdCons.Rows.RemoveAt(rowIndexFromMouseDown);
grdCons.Rows.Insert(targetIndex, rowToMove);
}
}
The problem lies in grdCons_DragDrop(). Because you mentioned the DGV is bound to a DataTable calling grdCons.Rows.Insert(targetIndex, rowToMove) will trigger an InvalidOperationException. When a DGV is data-bound you need to manipulate the DataSource rather than the DGV. Here's the correct way to call grdCons_DragDrop().
private void grdCons_DragDrop(object sender, DragEventArgs e)
{
DataTable tbl = (DataTable)grdCons.DataSource;
Point clientPoint = grdCons.PointToClient(new Point(e.X, e.Y));
int targetIndex = grdCons.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
if (e.Effect == DragDropEffects.Move)
{
DataRow row = tbl.NewRow();
row.ItemArray = tbl.Rows[rowIndexFromMouseDown].ItemArray; //copy the elements
tbl.Rows.RemoveAt(rowIndexFromMouseDown);
tbl.Rows.Insert(targetIndex, rowToMove);
}
}