Comunidad Gambas-es

Versión completa: Problema al arrastrar un control
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Buenas!.

Viendo un ejemplo de Cogier sobre Drag y Drop, creé algo similar. Pero cuando el objeto es arrastrado fuera del lugar donde debe estar,
este se borra y se elimina de su contenedor de origen.

Tengo un panel con tres etiquetas. Cada etiqueta tiene una palabra que forman una frase desordenada.
Se trata de llevar cada etiqueta al otro panel y que la frase se pueda ver ordenada.

Una vez el control se ha arrastrado o creado en el otro panel, debe ser eliminado del panel de origen.

Para probar el efecto debe ser arrastrado fuera de su contenedor y que no sea el panel 2.

[Imagen: xFFwNB5.png]

Al pulsar el botón de check se comprueba si el orden de la frase es correcto.

Este es el código.

GAMBAS
  1. Private aphrase As String[] = ["Order", "the", "phrase"]
  2. Private tobject As Object
  3.  
  4. Public Sub Form_Open()
  5.  
  6.   Dim lb As Label
  7.   Dim adisorderphrase As String[]
  8.  
  9.   adisorderphrase = aphrase.Copy()
  10.   adisorderphrase.Shuffle()
  11.  
  12.   Panel1.Arrangement = Arrange.Column
  13.  
  14.   For ICount As Integer = 0 To adisorderphrase.Max
  15.     lb = New Label(Panel1) As "words"
  16.     With lb
  17.       .text = adisorderphrase[ICount]
  18.       .Font.Size = 18
  19.       .Alignment = Align.Center
  20.       .AutoResize = True
  21.       .Padding = 5
  22.       .Border = Border.Plain
  23.     End With     
  24.   Next
  25.  
  26.  
  27. Public Sub words_enter()
  28.  
  29.   tobject = Last  
  30.   stext = Last.text
  31.  
  32.  
  33. Public Sub words_MouseDrag()
  34.  
  35.   If Mouse.left Then    
  36.     Last.Drag(Last.text)  
  37.     'If your drag to any place the control is deleted. :(
  38.     Last.Delete
  39.  
  40.  
  41. Public Sub Panels_Drop()
  42.  
  43.   Dim lb As Label
  44.     
  45.   If Drag.type = Drag.Text Then     
  46.     lb = New Label(Last) As "words"
  47.     With lb
  48.       .Text = Drag.Data      
  49.       .AutoResize = True
  50.       .W = Drag.Source.w
  51.       .H = Drag.Source.h
  52.       .Border = Border.Plain
  53.       .Font.Size = Drag.Source.Font.Size
  54.       .Padding = 5
  55.     End With    
  56.   'Drag.Source.Delete
  57.   'Is impossible delete the object here, the control is being dragged
  58.  
  59.  
  60. Public Sub Button1_Click()
  61.  
  62.   Dim wrong As Boolean
  63.     
  64.   If Panel2.Children.Count = aphrase.Count Then
  65.     For r As Integer = 0 To aphrase.Max
  66.       tobject = Panel2.Children[r]
  67.       If aphrase[r] <> tobject.text Then
  68.         wrong = True
  69.         Break
  70.       Endif
  71.     Next    
  72.     If wrong Then
  73.       Message.Error(("The order of words isn't correct"), "OK")      
  74.     Else
  75.       Message.Info(("The order of words is correct"), "OK")
  76.     Endif  
  77.   Else
  78.     Message.Error(("There aren't enough words on the panel"), "OK")
  79.  



Saludos
Me Confused parece que a mi funciona.
Cuando transporto el Control, que contiene una de las tres palabras, desde el Panel1 y lo coloco en el Panel2, el Control desaparece del Panel1.
(20-05-2023, 23:57)vuott escribió: [ -> ]Cuando transporto el Control, que contiene una de las tres palabras, desde el Panel1 y lo coloco en el Panel2, el Control desaparece del Panel1.

Intenta arrastrarlo al formulario y soltarlo en este, desaparecerá del Panel1.

Saludos
El problema puede deberse a que el elemento sobre el cual se crea el drag es eliminado en el mismo evento del drag.
GAMBAS
  1. Public Sub words_MouseDrag()
  2.  
  3.   If Mouse.left Then    
  4.     Last.Drag(Last.text)  
  5.     'If your drag to any place the control is deleted. :(
  6.     Last.Delete ' Esto tendrías que comentarlo
  7.  


(21-05-2023, 00:47)tincho escribió: [ -> ]El problema puede deberse a que el elemento sobre el cual se crea el drag es eliminado en el mismo evento del drag.

Eso es lo primero que intenté. Pero la eliminación del source se debe ejecutar en alguna parte. Para saber que control es,
o de donde proviene.

La información real que se traspasa es el texto, el control es lo de menos, se va a crear un control similar en el otro panel
con la información del control source. El problema reside en eliminar el control en el panel origen y desde donde debe realizarse
o como hacerse.

Tengo de hace años otro ejemplo con dos ListView y no me ocurre eso.

Gracias a los dos.

Saludos
(21-05-2023, 00:08)Shell escribió: [ -> ]Intenta arrastrarlo al formulario y soltarlo en este, desaparecerá del Panel1.

¿Quieres que el Control con el texto, si lo sueltas fuera de Panel2 (por ejemplo, en el Formulario), no desaparezca de Panel1 ?
(21-05-2023, 16:45)vuott escribió: [ -> ]¿Quieres que el Control con el texto, si lo sueltas fuera de Panel2 (por ejemplo, en el Formulario), no desaparezca de Panel1 ?

Eso es. Que solo se puede soltar en Panel2 o del Panel2 al Panel1 pero nunca al formulario.
Buenas!.

Parece que lo he solucionado.

Un control si no se destruye, se puede reutilizar. En este caso, parece lo más acertado.
Aparentemente no puedo destruir algo que se está arrastrando.

Por de pronto para que el formulario no admita que algo se pueda soltar en el, se puede hacer:

GAMBAS
  1. Public Sub Form_Open()
  2.  
  3.   Me.Drop = False
  4.  
  5.  End



¿ Qué es realmente lo que paso de un lado a otro ?.
¿ Cuál es la información ?.
El texto que contiene la etiqueta, no la etiqueta en si. Wink

Entonces puedo. Si sé que el panel 1 tiene tres etiquetas, creo el mismo número de etiquetas en el panel 2, pero en este las hago todas invisibles.
No vamos a crear más etiquetas, solo las necesarias.

Ahora bien, ¿ Cómo se va añadiendo la información a esas etiquetas ?. En orden.

Se comprueba cada una de las etiquetas del panel 2 ( si estamos pasando del panel 1 al panel 2 ),  la primera etiqueta
del panel 2 que este invisible y que su texto sea una cadena vacía, se hace visible y se le pasa el texto que se ha arrastrado.
Luego rompemos el bucle, para que no se llene de etiquetas con el mismo contenido.
Y hasta ahí parece que funciona.

GAMBAS
  1. Private aphrase As String[] = ["Order", "the", "phrase"]
  2. Private tobject As Object
  3.  
  4. Public Sub Form_Open()
  5.  
  6.   Dim lb As Label
  7.   Dim adisorderphrase As String[]
  8.  
  9.   Me.Drop = False
  10.  
  11.   adisorderphrase = aphrase.Copy()
  12.   adisorderphrase.Shuffle()
  13.  
  14.   Panel1.Arrangement = Arrange.Column
  15.  
  16.   For ICount As Integer = 0 To adisorderphrase.Max
  17.     lb = New Label(Panel1) As "words"
  18.     With lb
  19.       .text = adisorderphrase[ICount]
  20.       .Font.Size = 18
  21.       .Alignment = Align.Center
  22.       .AutoResize = True
  23.       .Padding = 5
  24.       .Tag = ICount
  25.       .Border = Border.Plain
  26.     End With
  27.     'palabras.Add(lb)     
  28.   Next
  29.   'Hago la misma operación, creo las etiquetas en el panel2, pero invisibles
  30.   For ICount As Integer = 0 To adisorderphrase.Max
  31.     lb = New Label(Panel2) As "words"
  32.     With lb
  33.       .text = ""
  34.       .Font.Size = 18
  35.       .Alignment = Align.Center
  36.       .AutoResize = True
  37.       .Padding = 5
  38.       .Visible = False 'Si no lo destruyo lo hago invisible
  39.       .Tag = ICount
  40.       .Border = Border.Plain
  41.     End With
  42.   Next
  43.  
  44.  
  45.  
  46. Public Sub words_enter()
  47.  
  48.   tobject = Last  
  49.   stext = Last.text
  50.  
  51.  
  52. Public Sub words_MouseDrag()
  53.  
  54.  
  55.   If Mouse.left Then    
  56.     Last.Drag(Last.text, "text/plain")
  57.  
  58.  
  59. Public Sub Button1_Click()
  60.  
  61.   Dim wrong As Boolean
  62.  
  63.   If Panel2.Children.Count = aphrase.Count Then
  64.     For r As Integer = 0 To aphrase.Max
  65.       tobject = Panel2.Children[r]
  66.       If aphrase[r] <> tobject.text Then
  67.         wrong = True
  68.         Break
  69.       Endif
  70.     Next    
  71.     If wrong Then
  72.       Message.Error(("The order of words isn't correct"), "OK")      
  73.     Else
  74.       Message.Info(("The order of words is correct"), "OK")
  75.     Endif  
  76.   Else
  77.     Message.Error(("There aren't enough words on the panel"), "OK")
  78.  
  79.  
  80. Public Sub Panels_Drop()
  81.  
  82.   Dim lb As Label
  83.       
  84.   If Drag.type = Drag.Text Then
  85.     For Each lb In Last.Children
  86.       If lb.Visible = False Then
  87.         lb.Visible = True
  88.         lb.Text = Drag.Data
  89.         Break
  90.       Endif
  91.     Next
  92.  
  93.   Drag.Source.Visible = False
  94.      



Tengo que traducir los textos, claro. Rolleyes

Os añado el código que funciona.

Siempre el verdadero problema es el entender el problema y como se debería hacer.

¿ Puedo borrar el control ?.
¿ Necesito borrar el control ?.
¿ Puedo reutilizar ese control ?.

Aún tiene un fallo menor, que es que la frase este en el orden correcto.

Saludos