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