Drag/Drop 在 FlowLayoutPanel 上添加标签

Drag/Drop Label onto FlowLayoutPanel

我正在尝试将标签从 FlowLayoutPanel 拖到另一个 FlowLayoutPanel.Im 可以拖动但它不会放下标签?

我的代码

    private void flp_DragEnter(object sender, DragEventArgs e)
    {
        if ((e.AllowedEffect & DragDropEffects.Link) != 0

        && e.Data.GetDataPresent(typeof(string)))

            e.Effect = DragDropEffects.Link;
    }

    private void flp_DragDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(typeof(Label)))
        {
            FlowLayoutPanel destination = (FlowLayoutPanel)sender;
            Control control = (Control)e.Data.GetData(typeof(Label));
            destination.Controls.Add(control);
            return;
        }
    }

    private void lbl_MouseDown(object sender, MouseEventArgs e)
    {
        DoDragDrop((sender as Label).Text, DragDropEffects.Link);
    }

可以将控件的Name设置为拖拽数据,然后在拖放时,根据名称找到控件,将其从父控件集合中移除,添加到目标面板控件集合中。为此:

  1. 为每个作为放置目标的控件设置 AllowDrop 属性。您示例中的目标控件可以是 FlowLayoutPanel 控件。
  2. 为每个拖动开始的控件处理 MouseDown 事件,并在处理程序中调用该控件的 DoDragDrop 事件并设置要拖动的数据。您示例中的移动控件是标签,此处的数据可以是 Name 控件。
  3. 处理 DragEnetr event of each target of drag and set e.Effect 以确定是否允许删除。这是您可以检查是否允许丢弃的地方。例如,您可以检查数据是否为字符串,字符串是否为控件名称。
  4. Hanlde DragDrop and use GetData method of e.Data 获取数据并在拖放时执行操作。此处的操作是从其当前父项中删除控件并将其添加到新父项中。

代码:

使用下面的代码,如果您将 control_MouseDown 分配给所有标签的 MouseDown 事件并将 panel_DragEnter 分配给两个流布局面板的 DragEnter 事件并且还分配panel_DragDropDragDrop 两个流布局面板的事件,您可以在两个流布局面板之间移动标签,也可以在面板中重新排序标签:

private void control_MouseDown(object sender, MouseEventArgs e)
{
    var control = sender as Control;
    this.DoDragDrop(control.Name, DragDropEffects.Move);
}

private void panel_DragEnter(object sender, DragEventArgs e)
{
    if (!e.Data.GetDataPresent(typeof(string)))
        return;

    var name = e.Data.GetData(typeof(string)) as string;
    var control = this.Controls.Find(name, true).FirstOrDefault();
    if (control != null)
    {
        e.Effect = DragDropEffects.Move;
    }
}

private void panel_DragDrop(object sender, DragEventArgs e)
{
    if (!e.Data.GetDataPresent(typeof(string)))
        return;

    var name = e.Data.GetData(typeof(string)) as string;
    var control = this.Controls.Find(name, true).FirstOrDefault();
    if (control != null)
    {
        control.Parent.Controls.Remove(control);
        var panel = sender as FlowLayoutPanel;
        ((FlowLayoutPanel)sender).Controls.Add(control);
    }
}