Faraday
Faraday

Reputation: 2954

How can I perform a DragDrop/swap of a ChartControl?

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
                                    };

Upvotes: 0

Views: 1147

Answers (1)

Uranus
Uranus

Reputation: 1690

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;
}

}

Upvotes: 1

Related Questions