Перетаскивание и перемещение нескольких объектов из элемента управления ListView в элемент управления TreeView

В данной краткой статье приводится описания перетаскивания и перемещения нескольких объектов из элемента управления ListView в элемент управления TreeView. Также описывается использование события GiveFeedback для изменения курсора по умолчанию при выполнении операции перетаскивания. Я привожу наиболее простые примеры. Выполните следующие действия.

Действие 1. Откройте Visual Studio > Файл > Создать > Проект. На панели «Типы проектов» выберите необходимый язык программирования (Visual C# или Visual Basic). На панели «Шаблоны» выберите «Приложение Windows». Выберите имя и местоположение проекта и нажмите OK.

Действие 2. Перетащите в форму элементы управления ListView и TreeView (listView1 и treeView1). Для события Form_Load() сначала выполняется наполнение элементов ListView и TreeView примерами данных. Чтобы включить перетаскивание в среде выполнения, мы будем выполнять обработку 3 основных событий в рамках всей операции перетаскивания. Давайте посмотрим, чему соответствуют эти события:

событие ListView_ItemDrag – событие вызывается для элемента управления ListView, когда пользователь начинает перетаскивать узлы ListView;

событие TreeView_DragEnter – данное событие вызывается для элемента управления TreeView при перетаскивании объектов в границы элемента управления TreeView;

событие TreeView_DragDrop – данное событие вызывается при завершении операции перетаскивания.

Действие 3. Теперь следует добавить следующий код в событие Form_Load, чтобы заполнить данными элементы управления ListView и TreeView, а также зарегистрировать события перетаскивания.

C#

private void Form1_Load(object sender, EventArgs e)

{

    listView1.ItemDrag += new ItemDragEventHandler(listView1_ItemDrag);

    treeView1.DragEnter += new DragEventHandler(treeView1_DragEnter);

    treeView1.DragDrop += new DragEventHandler(treeView1_DragDrop);

    PopulateListViewTreeView();

}

 

private void PopulateListViewTreeView()

{

    List<string> lst = new List<string>();

    lst.Add("Item1");

    lst.Add("Item2");

    lst.Add("Item3");

    lst.Add("Item4");

    lst.Add("Item5");

    lst.Add("Item6");

 

    // Populate ListView

    for (int i = 0; i < lst.Count; i++)

    {

        ListViewItem lvItem = new ListViewItem(lst[i].ToString());

        listView1.Items.Add(lvItem);

        lvItem.EnsureVisible();

    }

 

    // Populate TreeView

    for (int i = 0; i < lst.Count; i++)

    {

        TreeNode node = new TreeNode(lst[i].ToString());

        if (i % 2 == 0)

            treeView1.Nodes.Add(node);

        else

            treeView1.Nodes[0].Nodes.Add(node);

        node.EnsureVisible();

    }

    treeView1.ExpandAll();

    treeView1.AllowDrop = true;

}

VB.NET

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
      AddHandler listView1.ItemDrag, AddressOf listView1_ItemDrag
      AddHandler treeView1.DragEnter, AddressOf treeView1_DragEnter
      AddHandler treeView1.DragDrop, AddressOf treeView1_DragDrop
      PopulateListViewTreeView()
End Sub
 
Private Sub PopulateListViewTreeView()
      Dim lst As List(Of String) = New List(Of String)()
      lst.Add("Item1")
      lst.Add("Item2")
      lst.Add("Item3")
      lst.Add("Item4")
      lst.Add("Item5")
      lst.Add("Item6")
 
      ' Populate ListView
      For i As Integer = 0 To lst.Count - 1
            Dim lvItem As ListViewItem = New ListViewItem(lst(i).ToString())
            listView1.Items.Add(lvItem)
            lvItem.EnsureVisible()
      Next i
 
      ' Populate TreeView
      For i As Integer = 0 To lst.Count - 1
            Dim node As TreeNode = New TreeNode(lst(i).ToString())
            If i Mod 2 = 0 Then
                  treeView1.Nodes.Add(node)
            Else
                  treeView1.Nodes(0).Nodes.Add(node)
            End If
            node.EnsureVisible()
      Next i
      treeView1.ExpandAll()
      treeView1.AllowDrop = True
End Sub

Действие 4. Затем следует добавить код для реагирования на действия обработчиков событий.

C#

private void listView1_ItemDrag(object sender, ItemDragEventArgs e)

{

    listView1.DoDragDrop(listView1.SelectedItems, DragDropEffects.Move);

}

 

private void treeView1_DragEnter(object sender, DragEventArgs e)

{

    if (e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection)))

        e.Effect = DragDropEffects.Move;

}

 

private void treeView1_DragDrop(object sender, DragEventArgs e)

{

    if (e.Data.GetDataPresent(typeof(ListView.SelectedListViewItemCollection).ToString(), false))

    {

        Point loc = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));

        TreeNode destNode = ((TreeView)sender).GetNodeAt(loc);

        TreeNode tnNew;

 

        ListView.SelectedListViewItemCollection lstViewColl =

            (ListView.SelectedListViewItemCollection)e.Data.GetData(typeof(ListView.SelectedListViewItemCollection));

        foreach (ListViewItem lvItem in lstViewColl)

        {

            tnNew = new TreeNode(lvItem.Text);

            tnNew.Tag = lvItem;

 

            destNode.Nodes.Insert(destNode.Index + 1, tnNew);

            destNode.Expand();

            // Remove this line if you want to only copy items

            // from ListView and not move them

            lvItem.Remove();

        }

    }

}

VB.NET

Private Sub listView1_ItemDrag(ByVal sender As Object, ByVal e As ItemDragEventArgs)
      listView1.DoDragDrop(listView1.SelectedItems, DragDropEffects.Move)
End Sub
 
Private Sub treeView1_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs)
      If e.Data.GetDataPresent(GetType(ListView.SelectedListViewItemCollection)) Then
            e.Effect = DragDropEffects.Move
      End If
End Sub
 
Private Sub treeView1_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs)
      If e.Data.GetDataPresent(GetType(ListView.SelectedListViewItemCollection).ToString(), False) Then
            Dim loc As Point = (CType(sender, TreeView)).PointToClient(New Point(e.X, e.Y))
            Dim destNode As TreeNode = (CType(sender, TreeView)).GetNodeAt(loc)
            Dim tnNew As TreeNode
 
            Dim lstViewColl As ListView.SelectedListViewItemCollection = CType(e.Data.GetData(GetType(ListView.SelectedListViewItemCollection)), ListView.SelectedListViewItemCollection)
            For Each lvItem As ListViewItem In lstViewColl
                  tnNew = New TreeNode(lvItem.Text)
                  tnNew.Tag = lvItem
 
                  destNode.Nodes.Insert(destNode.Index + 1, tnNew)
                  destNode.Expand()
                  ' Remove this line if you want to only copy items
                  ' from ListView and not move them
                  lvItem.Remove()
            Next lvItem
      End If
End Sub

Как показано в приведенном выше коде, событие ItemDrag вызывается из элемента управления ListView, как только пользователь начинает перетаскивать узел ListView. Метод DoDragDrop вызывает процедуру перетаскивания в отношении выбранных объектов ListView.

Событие DragEnter происходит, когда объект ListViewNode перетаскивается из элемента управления ListView в элемент управления TreeView. При этом событии мы проверяем действительность операции перетаскивания, а именно, что перетаскиваемые данные – это набор данных, выбранных в элементе управления ListView.

Наконец, событие DragEnter происходит, когда объект ListViewNode отпускается в точке назначения в элементе управления TreeView. Вычисляется точка отпускания и извлекаются объекты ListViewNode (которые необходимо добавить в узел назначения) путем прохождения цикла по коллекции SelectedListViewItemCollection. Это весь код, который необходим для операции перетаскивания.

Действие 5. Я добавил это последнее действие в основном для того, чтобы рассказать об удобном событии, имеющем отношение к операции перетаскивания: событие GiveFeedback. Событие GiveFeedback происходит в рамках операции перетаскивания и позволяет источнику события перетаскивания изменять внешний вид курсора мыши при наведении на подходящую цель. Данное действие обеспечивает представление другой картинки пользователю во время операции перетаскивания. Это значит, что, если у вас есть свой собственный файл курсора, то с помощью данного события его можно легко отобразить пользователям во время операции перетаскивания.

Пример использования данного события представлен ниже.

C#

private void listView1_GiveFeedback(object sender, GiveFeedbackEventArgs e)

{

    e.UseDefaultCursors = false;

    if ((e.Effect & DragDropEffects.Move) == DragDropEffects.Move)

        Cursor.Current = Cursors.Cross;

    else

        Cursor.Current = Cursors.Default ;

}

VB.NET

Private Sub listView1_GiveFeedback(ByVal sender As Object, ByVal e As GiveFeedbackEventArgs)
      e.UseDefaultCursors = False
      If (e.Effect And DragDropEffects.Move) = DragDropEffects.Move Then
            Cursor.Current = Cursors.Cross
      Else
            Cursor.Current = Cursors.Default
      End If
End Sub

Вот так вы можете создать свой собственный файл курсора, доступный для просмотра пользователями.

В данной статье шла речь о перетаскивании и перемещении нескольких объектов из элемента управления ListView в элемент управления TreeView. Также поднимался вопрос изменения вида курсора по умолчанию во время операции перетаскивания. Я надеюсь, что данная статья была полезна. Благодарю за внимание.

Если вам понравилась статья, подпишитесь на мой канал RSS.