Search code examples
c#drag-and-dropcustom-controlsdraggableflowlayoutpanel

Drag and drop a CustomControl working only from it's background


I have a custom control containing a button with a label underneath. I want to make these controls to be draggable over another one to arrange them as I want in a flowlayoutpanel. Now is working only if I drag the control from it's background (marked with yellow in the picture bellow) to the other control's yellow marked area, but not if i drag from the button or label area..

enter image description here

How can I make it so I can move the custom control no matter from where I grab and drop it on the other control. Basically to be only one control not like a container for the button and label..

This is my code so far:

 private void flowLayoutPanel1_DragEnter(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Move;
    }

    private void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
    {         
        CustomControl target = sender as CustomControl;
        if (target != null)
        {
            int targetIndex = FindCSTIndex(target);
            if (targetIndex != -1)
            {
                string pictureBoxFormat = typeof(CustomControl).FullName;
                if (e.Data.GetDataPresent(pictureBoxFormat))
                {
                    CustomControl source = e.Data.GetData(pictureBoxFormat) as CustomControl;

                    int sourceIndex = this.FindCSTIndex(source);

                    if (targetIndex != -1)
                        this.flowLayoutPanel1.Controls.SetChildIndex(source, targetIndex);
                }
            }
        }
    }

    private int FindCSTIndex(CustomControl cst_ctr)
    {
        for (int i = 0; i < this.flowLayoutPanel1.Controls.Count; i++)
        {    
            CustomControl target = this.flowLayoutPanel1.Controls[i] as CustomControl;

            if (cst_ctr == target)
                return i;
        }
        return -1;
    }

    private void OnCstMouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            CustomControl cst = sender as CustomControl;
            cst.DoDragDrop(cst, DragDropEffects.Move);
        }
    }

And the custom control class:

public class CustomControl : Control
{
    private Button _button;
    private Label _label;

    public CustomControl(Button button, Label label)
    {
        _button = button;
        _label = label;
        button.Width = 50;
        button.Height = 50;
        label.Width = 65;
        button.BackgroundImageLayout = ImageLayout.Stretch;
        Height = button.Height + label.Height;
        Width = 68;

        // Width = Math.Max(button.Width, label.Width);
        Controls.Add(_button);
        _button.Location = new Point(0, 0);
        Controls.Add(_label);
        _label.Location = new Point(0, button.Height);
    }
}

Solution

  • Managed to solve it:

    private void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
        {
            Control target = new Control();
    
            target.Parent = sender as Control;
    
                if (target != null)
                {
                    int targetIndex = FindCSTIndex(target.Parent);
                    if (targetIndex != -1)
                    {
                        string cst_ctrl = typeof(CustomControl).FullName;
                        if (e.Data.GetDataPresent(cst_ctrl))
    
                        {
                            Button source = new Button();
                            source.Parent = e.Data.GetData(cst_ctrl) as CustomControl;
    
                            if (targetIndex != -1)
                                this.flowLayoutPanel1.Controls.SetChildIndex(source.Parent, targetIndex);
                        }
                    }
                }
            }
    
        private int FindCSTIndex(Control cst_ctr)
        {
            for (int i = 0; i < this.flowLayoutPanel1.Controls.Count; i++)
            {    
                CustomControl target = this.flowLayoutPanel1.Controls[i] as CustomControl;
    
                if (cst_ctr.Parent == target)
                    return i;
            }
            return -1;
        }
    
        private void OnCstMouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Control cst = sender as Control;
                cst.DoDragDrop(cst.Parent, DragDropEffects.Move);
            }
        }