Using the FlowLayoutPanel and Reordering with Drag and Drop






4.81/5 (41 votes)
Using the FlowLayoutPanel and reordering with drag and drop.
Introduction
The FlowLayoutPanel
control is actually pretty handy from time to time. In this article, I will explain how to enable drag and drop on two controls. I am using a custom progressbar with drag and drop enabled, so this will only show how to drop and reorder controls. As always, there is probably more than one way to solve this, but this is how I did.
Background
Recently, I had to create a custom drawn progressbar and somehow create a list of those with drag and drop functions. After searching the Internet for a while without luck, I decided to write a little helper here once I finished.
Using the Code
To be able to drag controls to the panel, we first have to add the DragEnter
event, either by code or in the Designer.
this.flowLayoutPanel1.DragEnter += new DragEventHandler(flowLayoutPanel_DragEnter);
void flowLayoutPanel_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}
Then, we add the actual drop event and write the code for it. First, I check if I have dragged the control to the same FlowLayoutPanel
. If that's the case, I reorder; if not, then I first add the control and then reorder. The reordering is based on which child control I "drop" the new control on.
this.flowLayoutPanel1.DragDrop += new DragEventHandler(flowLayoutPanel_DragDrop);
void flowLayoutPanel1_DragDrop(object sender, DragEventArgs e)
{
HarrProgressBar data = (HarrProgressBar)e.Data.GetData(typeof(HarrProgressBar));
FlowLayoutPanel _destination = (FlowLayoutPanel)sender;
FlowLayoutPanel _source = (FlowLayoutPanel)data.Parent;
if (_source != _destination)
{
// Add control to panel
_destination.Controls.Add(data);
data.Size = new Size(_destination.Width, 50);
// Reorder
Point p = _destination.PointToClient(new Point(e.X, e.Y));
var item = _destination.GetChildAtPoint(p);
int index = _destination.Controls.GetChildIndex(item, false);
_destination.Controls.SetChildIndex(data, index);
// Invalidate to paint!
_destination.Invalidate();
_source.Invalidate();
}
else
{
// Just add the control to the new panel.
// No need to remove from the other panel,
// this changes the Control.Parent property.
Point p = _destination.PointToClient(new Point(e.X, e.Y));
var item = _destination.GetChildAtPoint(p);
int index = _destination.Controls.GetChildIndex(item, false);
_destination.Controls.SetChildIndex(data, index);
_destination.Invalidate();
}
}
This will move the control from one panel to another. This code will probably need some tuning if you want to drag from a normal Panel
to a FlowLayoutPanel
.
Points of Interest
I've put DoDragDrop();
in the HarrProgressBar
to be able to drag it onto other controls and to minimize code outside the class.
History
- 2009-12-21 - v1.0 - Article added.