WPF: как реализовать перетаскивание с помощью вложенных (иерархических) элементов управления - PullRequest
7 голосов
/ 21 февраля 2009

Используя WPF, мне удалось реализовать перетаскивание, чтобы изменить порядок элементов в списке (представление или поле), а также перетаскивать элементы между списками.

Теперь я пытаюсь понять, как реализовать перетаскивание с помощью списков NESTED.

Например, у меня есть представление списка, содержащее проекты, и каждый элемент проекта содержит другое представление списка задач. Я хочу иметь возможность перетаскивать, чтобы изменить порядок проектов, а также изменить порядок задач и перемещать их между проектами.

У меня есть код, который успешно выполняет одно из другого, но я не могу понять, как сделать то и другое.

Кажется, что есть какое-то болезненное решение, которое включало бы проверку попаданий и, возможно, z-порядок вложенных списков, но я не могу найти никаких примеров этого.

Кто-нибудь может предложить какие-нибудь указатели?

К вашему сведению: рабочий код, который я в настоящее время реализовал, основан на следующих двух превосходных статьях о перетаскивании WPF:

http://bea.stollnitz.com/blog/?p=53 http://www.codeproject.com/KB/WPF/ListViewDragDropManager.aspx

Ответы [ 4 ]

4 голосов
/ 06 августа 2009

Поскольку MouseMove и большинство других в wpf являются маршрутизируемыми событиями, вы можете просто проверить e.OriginalSource в общем обработчике событий. Затем вы можете решить, какой элемент перетаскивать, основываясь на том, на каком элементе была мышь, возможно, используя один из тех методов поиска помощника «найти родителя, который удовлетворяет условию». Кроме того, вы можете установить e.Handled, если у вас есть несколько элементов в визуальном дереве, подписывающихся на событие.

2 голосов
/ 21 февраля 2009

Просто сначала подумайте, почему бы не использовать TreeView вместо ListView, если вы собираетесь иметь вложение?

0 голосов
/ 02 ноября 2009

Я столкнулся с аналогичной проблемой при работе с приложением со списками вложенных пользовательских элементов управления.
Я обработал все это в PreviewMouseButtonDown event на уровне управления. Я проверяю координаты точки, по которой щелкнули. Если оно пришло откуда-либо из родительского ListBoxItem, которого не было в ListBox, я обработал DragDrop.DoDragDrop() там. Если он пришел изнутри ListBoxItem, я опустил его до дочерней ListBox PreviewMouseButtonDown event. Я проверяю, где находится местоположение в дочернем ListBox, чтобы увидеть, на каком элементе щелкнули, чтобы я мог взять его и вместо этого выполнить DragDrop на этом уровне.

Псевдокод выглядит следующим образом:

Parent ListBox  
--  PListBoxItem1  
--  PListBoxItem2  
--  PListBoxItem3  
----    Child ListBox  
------  Child ListBoxItem1  
------  Child ListBoxItem2  -Click drag started here  
------  Child ListBoxItem3  

Код:

Parent_List_Box_PreviewMouseButtonDown  
If mouse position is not inside the Child ListBox Then  
  DoDragDrop() on the Parent level with this ListBoxItem  
End If

Child_ListBox_PreviewMouseButtonDown  
Determine which item the mouse was clicked on relative to the Child ListBox  
DoDragDrop() on the Child level with this ListBoxItem  

Таким образом, поскольку click был внутри Child's ListBox, событие всплывает до самого нижнего обработчика, который отвечает критериям для DragEvent.

Надеюсь, это поможет!

0 голосов
/ 06 августа 2009

AllowDrop должен быть истинным для любого элемента управления.

...