2009-02-20 16 views
7

El uso de WPF que he tenido éxito en la aplicación de arrastrar y soltar para reorganizar los elementos dentro de una lista (ver o caja) y también para arrastrar y soltar elementos entre las listas.WPF: Cómo implementar arrastrar y soltar con anidada (jerárquica) controla

Ahora estoy tratando de encontrar la manera de implementar arrastrar y soltar con listas anidadas.

Por ejemplo tengo una vista de lista que contiene los proyectos y cada elemento de proyecto contiene otra vista de lista de tareas. Quiero ser capaz de arrastrar y soltar para reorganizar el orden de los proyectos y también para reordenar las tareas y moverlas entre proyectos.

que tienen código que hace con éxito una de la otra, pero no puedo encontrar la manera de hacer ambas cosas.

Parece que hay algún tipo de solución dolorosa que implicaría la prueba y tal vez el orden z de las listas anidadas golpeado, pero no puedo encontrar ningún ejemplo de esto.

¿Alguien puede ofrecer alguna sugerencia?

FYI: El código de trabajo que actualmente tiene en marcha se basa en los siguientes dos excelentes artículos sobre WPF arrastrar y soltar:

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

Respuesta

2

Justo primer pensamiento es, por qué no utilizar un TreeView vez de un ListView si va a anidar?

+0

Buena idea ... Creo que eso simplificaría la implementación de la funcionalidad de arrastrar y soltar ...pero me daría algunos nuevos desafíos de apariencia y sensación de UI ... – Scrappydog

0

AllowDrop debe ser cierto en cualquier control.

4

Dado que MouseMove y la mayoría de los demás en wpf son eventos enrutados, puede simplemente marcar e.OriginalSource en un controlador de eventos comunes. A continuación, puede decidir qué elemento arrastrar según el elemento en el que se encontraba el mouse, probablemente utilizando una de las técnicas de método auxiliar "encontrar padre que satisface la condición". Además, puede establecer e.Handled si tiene varios elementos en el árbol visual que se suscriben al evento.

+0

¡Esto es lo que necesitaba! Gracias –

+0

Llegué aquí buscando específicamente qué podría ser ese método "encontrar padre que satisface la condición", y la condición suele ser "de tipo". Hay una implementación genérica 'FindParent ' que utiliza el método 'VisualTreeHelper.GetParent (child)': http://www.infragistics.com/community/blogs/blagunas/archive/2013/05/29/find-the-parent -control-de-un-tipo-específico-en-wpf-y-silverlight.aspx – Triynko

0

pasé por un problema similar cuando se trabaja en una aplicación con cuadros de lista de controles de usuario anidados.
Manejé todo esto en el PreviewMouseButtonDown event en un nivel de control. Compruebo las coordenadas del punto en el que se hizo clic. Si proviene de cualquier lugar en el padre ListBoxItem que no estaba en el ListBox, proceso allí el DragDrop.DoDragDrop(). Si vino desde el interior del ListBoxItem, lo dejo burbujear hasta el PreviewMouseButtonDown event de ListBox. Compruebo para ver dónde está la ubicación en el ListBox secundario para ver en qué elemento se hizo clic, así que puedo tomarlo y hacer el DragDrop en este nivel.

El pseudo-código es el siguiente:

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

Código:

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 

Así que desde el click estaba dentro de una Child's ListBox, el evento se propaga hacia el controlador más bajo que pasa con los criterios de el DragEvent.

Espero que esto ayude!