ComponentOne controls provide support for Drag-and-Drop operations within different controls using C1DragDropManager. With this blog we will discuss a user scenario where we will perform the Drag-and-Drop operation between two ComponentOne Controls C1TreeView and C1FlexGrid.

To perform Drag-and-Drop operation between any two controls we need a mediator. And in such a scenario, C1DragDropManager comes into the picture which provides the facility to perform Drag-and-Drop operation anywhere within the ComponentOne Controls. Following are the steps demonstrating – “How to perform drag-and-drop operation between C1TreeView and C1FlexGrid”.

Registering Source and Target with C1DragDropManager


Step1: The very first step we require is that you bind the Source and Target with C1DragDropManager after performing all declarations and initializations.



void register()
{
dd.RegisterDragSource(c1TreeView, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(c1TreeViewItem, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(emp1, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(e1, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(pr, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(dt, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(ind, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(emp2, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(e2, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(dn, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(dv, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDragSource(us, DragDropEffect.Copy, ModifierKeys.None, true);
dd.RegisterDropTarget(c1FlexGrid, true);

ddm.RegisterDropTarget(c1TreeViewItem, true);
}



Note: Since the C1DragDropManager.RegisterDragSource() method takes the argument only as a type of UIElement, we need to override the CellFactory of C1FlexGrid and register each row as follows:



public class DragDropCellFactory : CellFactory
{
private C1DragDropManager _ddm;
public DragDropCellFactory(C1DragDropManager ddm)
{
_ddm = ddm;
}
public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange rng)
{
base.CreateCellContent(grid, bdr, rng);
bdr.Tag = grid.Rows[rng.Row]; //used to find the actual row dragged
_ddm.RegisterDragSource(bdr, DragDropEffect.Move, ModifierKeys.None);
}
}


Performing Drag and Drop Operations within C1TreeView and C1FlexGrid


Step2: In our scenario, we have used two different C1DragDropManager object to perform inter-control drag-drop operation. Therefore, the next step is to apply the conversion logic into the DragStart and DragDrop Events of C1DragDropManager. Here is the suggested code:

a) To perform drag-drop operation from C1TreeView to C1FlexGrid:



dd.DragStart += (s, e) =>
{
try
{
treeItem = e.DragSource as C1TreeViewItem;
}
catch (Exception ee)
{
MessageBox.Show("Can not drag this element! Please try another one.");
}
};

dd.DragDrop += (s, e) =>
{
try
{
var grid = e.DropTarget as C1FlexGrid;
if (grid.Name == "c1FlexGrid")
{
if (flag)
{
grid[row, col] = treeItem.Header.ToString();
flag = false;
}
else
{
if (treeItem.Items.Count > 1)
{
emp.Add(new Employee()
{
ID = (treeItem.Items[0] as C1TreeViewItem).Header.ToString(),
Name = (treeItem.Items[1] as C1TreeViewItem).Header.ToString(),
Department = (treeItem.Items[2] as C1TreeViewItem).Header.ToString(),
Location = (treeItem.Items[3] as C1TreeViewItem).Header.ToString()
});
}
else
emp.Add(new Employee()
{
ID = treeItem.Header.ToString(),
Name = treeItem.Header.ToString(),
Department = treeItem.Header.ToString(),
Location = treeItem.Header.ToString()
});
}
}
}
catch (Exception ee)
{
MessageBox.Show("Can not drop this element! Please try another one.");
}
};


b) To perform drag-drop operation from C1FlexGrid to C1TreeView:



ddm.DragStart += (s, e) =>
{
try
{
var bdr = e.DragSource as Border;
var row = (bdr.Tag as Row);
var flex = (bdr.Tag as Row).Grid;
ddm.TargetMarker.Width = flex.ActualWidth; //configure the Target Marker
}
catch (Exception ee)
{
MessageBox.Show("Can not drag this element! Please try another one.");
}
};

ddm.DragDrop += (s, e) =>
{
try
{
var bdr = e.DragSource as Border;
var treeview = e.DropTarget as C1TreeViewItem;
if (treeview.Name == "c1TreeViewItem") //check the actual drop target
{
int index = c1FlexGrid.Selection.Row;
C1TreeViewItem item = new C1TreeViewItem();
item.Header = c1FlexGrid[index, 0];
for (int i = 0; i < c1FlexGrid.Columns.Count; i++)
{
C1TreeViewItem subitem = new C1TreeViewItem();
subitem.Header = c1FlexGrid[index, i];
dd.RegisterDragSource(subitem, DragDropEffect.Copy, ModifierKeys.None, true);
item.Items.Add(subitem);
}
dd.RegisterDragSource(item, DragDropEffect.Copy, ModifierKeys.None, true);
treeview.Items.Add(item);
}
}
catch (Exception ee)
{
MessageBox.Show("Can not drop this element! Please try another one.");
}
};

theme.Apply(this);
tb.Width = myPanel.Width;
}



Like this, you can perform drag-drop operation between any two or more C1Controls.

See it in action!!!

Blog_Demo

Download Sample