Перетащите метку на FlowLayoutPanel

Я пытаюсь перетащить метку из FlowLayoutPanel в другую FlowLayoutPanel. Я могу перетаскивать, но метка не отбрасывается?

Мой код

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

person AndroidAL    schedule 22.02.2016    source источник
comment
Вы перетаскиваете текст метки, но ожидаете, что метка будет удалена.   -  person Zohar Peled    schedule 22.02.2016


Ответы (1)


Вы можете установить Name элементов управления как данные перетаскивания, а затем при удалении найти элемент управления по имени, удалить его из коллекции родительских элементов управления и добавить в коллекцию элементов управления целевой панели. Для этого:

  1. Установите AllowDrop для каждого элемента управления, который является целью удаления. Целевыми элементами управления в вашем примере могут быть оба элемента управления FlowLayoutPanel.
  2. Обработать событие MouseDown для каждого элемента управления, с которого начинается перетаскивание, и в вызове обработчика DoDragDrop этого элемента управления и установите данные, которые вы хотите перетащить. Движущиеся элементы управления в вашем примере — это метки, и данные здесь могут быть Name элементами управления.
  3. Обработка DragEnetr событие каждой цели перетаскивания и установки e.Effect, чтобы определить, разрешен ли сброс. Здесь вы можете проверить, разрешено ли падение. Например, вы можете проверить, являются ли данные строкой, а строка является именем элемента управления.
  4. Ханльде DragDrop и используйте метод GetData из e.Data для получения данных и выполнения действий при перетаскивании. Действие здесь заключается в удалении элемента управления из его текущего родителя и добавлении его к новому родителю.

Код:

Используя приведенный ниже код, если вы назначите события control_MouseDown для MouseDown всех меток и назначите событие panel_DragEnter для DragEnter обеих панелей макета потока, а также назначите событие panel_DragDrop для DragDrop обеих панелей макета потока, вы также можете перемещать метки между обеими панелями макета потока. вы можете изменить порядок меток на панели:

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);
    }
}
person Reza Aghaei    schedule 22.02.2016
comment
Именно то, что я хотел :), как бы я изменил цвет этикетки в зависимости от того, на какой панели была? - person AndroidAL; 22.02.2016
comment
В panel_DragDrop вы можете проверить panel.Name и принять решение на основе названия панели. Также вы можете обрабатывать событие ControlAdded для каждой панели и устанавливать событие e.Control.BackColor. - person Reza Aghaei; 22.02.2016
comment
Большое спасибо, не могли бы вы привести пример, используя код выше? - person AndroidAL; 22.02.2016
comment
Добро пожаловать :) изменение BackColor с помощью события ControlAdded не составляет большого труда и может быть легко выполнено. Мы должны сохранить эту ветку только о перетаскивании, чтобы быть более полезной для будущих читателей. Код: private void panel1_ControlAdded(object sender, ControlEventArgs e) { e.Control.BackColor = Color.Blue; } сделайте то же самое для другой панели макета потока и назначьте обработчики событий. Вероятно, вы можете решить проблему, используя этот комментарий, но если вам нужна дополнительная помощь, не стесняйтесь задавать вопрос об изменении BackColor элемента управления на основе родителя после удаления :) - person Reza Aghaei; 22.02.2016
comment
В качестве другого варианта взгляните на этот пост: Как перетащить кнопку с одной панели на другую? - person Reza Aghaei; 04.10.2016