https://foro.gambas-es.org/viewtopic.php?f=1&t=8123
-----------------------------------
Shell
Viernes, 26 Junio 2020, 13:27

Eliminar Un Objeto De Su Contenedor Padre
-----------------------------------
Buenas!.

Después de ver el mensaje de GambaFeliz en este post:

[url=https://foro.gambas-es.org/viewtopic.php?f=1&t=8122&p=48935#p48935]Problema con los indices en un contenedor padre al eliminar objetos contenidos

Antes de nada diré. ¿ No decimos que la propiedad Children devuelve una colección ?. ¿ Es realmente una colección o  es un array ?.  :roll: 
Aparenta ser más un array de controles, que no una colección de controles.. 8) 

Tengo un formulario con una matriz de n botones de ancho por n botones de alto. Y quiero eliminar o hacerlos "invisibles" con el ratón los que quiera. 
La parte importante es esta, pero fijaros en el comentario que digo de la propiedad visible del control botón y su padre Panel.

Sobre todo es importante que tengamos en cuenta la propiedad "Tag". 

[code linenumbers=false syntax=gambas]
Public Sub Observador_Click()
  
  Dim unboton As Button
  Dim indice As Integer
  
  indice = Last.tag
  
  For Each unboton In Panel1.Children     
    'Eliminar el botón del panel
    'If unboton.tag = indice Then unboton.Delete            
    
    ' ¿ Y si quieres hacerlo invisible ?. Si usas la propiedad visible, desparece de la vista del contenedor padre pero no evita que se redistribuyen los "niños"
    'Entonces...y si lo hacemos invisible de otra forma...B-D
    
    If unboton.Tag = indice Then
      With unboton
        .Border = Border.None
        .Tag = ""
        .Text = ""
      End With      
    Endif
    
  Next
  
End
[/code]

Haciéndolos "invisibles"

 [img]https://foro.gambas-es.org/files/images/768/eliminarhaciendoinvisible.png[/img] 

Y eliminando los que queramos del panel.

 [img]https://foro.gambas-es.org/files/images/768/eliminandolodeltodo.png[/img]

Saludos


-----------------------------------
Shell
Viernes, 26 Junio 2020, 13:34

Re: Eliminar Un Objeto De Su Contenedor Padre
-----------------------------------
Preguntaros esto:

Si la propiedad Children fuera una colección. ¿ Tengo necesidad de recorrer "todo" los elementos para hacer algo concreto con un solo objeto ?.

El código sigue teniendo un problema al cambiar el tag a texto, quiere un entero (eso en el caso de querer que sean invisibles).... :roll: 
Habrá que saber si ya fue pulsado el botón o eliminar la nueva asignación de tag dentro del with. 

De todas formas a lo mejor puede no interesar que se vuelva a comprobar algo que ya se ha pulsado .   :-D 

Saludos


-----------------------------------
Shell
Viernes, 26 Junio 2020, 13:56

Re: Eliminar Un Objeto De Su Contenedor Padre
-----------------------------------
Se puede añadir un array global tal que este:

[code linenumbers=false syntax=gambas]
...
Private pulsados As New Boolean[]
...
[/code]

En el form_open() cambiar el tamaño de este según el número de botones alto x ancho

[code linenumbers=false syntax=gambas]

 pulsados.Resize(BOTONESXANCHO * BOTONESXALTO)

[/code]

Y ademas evita un nuevo recorrido si ya se ha pulsado el botón..

[code linenumbers=false syntax=gambas]
Public Sub Observador_Click()
  
  Dim unboton As Button
  Dim indice As Integer
  
  indice = Last.tag
  
  If pulsados[indice] = False Then
    
    For Each unboton In Panel1.Children     
      'Eliminar el botón del panel
      'If unboton.tag = indice Then unboton.Delete            
      
      ' ¿ Y si quieres hacerlo invisible ?. 
      ' Si usas la propiedad visible, desparece de la vista del contenedor padre pero no evita que se redistribuyen los "niños"
      ' Entonces...y si lo hacemos invisible de otra forma...B-D
      
      If unboton.Tag = indice Then
        pulsados[unboton.Tag] = True
        With unboton
          .Border = Border.None          
          .Text = ""
        End With      
      Endif    
    Next  
  Endif
  
End
[/code]


Podía haber usado en la comprobación..

[code linenumbers=false syntax=gambas]
 If Not pulsados[indice] Then
[/code]


Saludos


-----------------------------------
Shell
Viernes, 26 Junio 2020, 14:05

Re: Eliminar Un Objeto De Su Contenedor Padre
-----------------------------------
Y dicho sea de paso para que no veamos como reacciona el botón "invisible"....podemos poner la propiedad "enable" a "False"  del botón:

[code linenumbers=false syntax=gambas]
....
If unboton.Tag = indice Then
        pulsados[unboton.Tag] = True
        With unboton
          .Border = Border.None          
          .Text = ""
          .Enabled = False
        End With      
      Endif    
...
[/code]

Y con esto y un bizcocho, buen fin de semana a todos..no corráis.. :twisted: 

Saludos


-----------------------------------
gambafeliz
Viernes, 26 Junio 2020, 19:39

Re: Eliminar Un Objeto De Su Contenedor Padre
-----------------------------------
[quote user="Shell" post="48945"]Buenas!.

Después de ver el mensaje de GambaFeliz en este post:

[url=https://foro.gambas-es.org/viewtopic.php?f=1&t=8122&p=48935#p48935]Problema con los indices en un contenedor padre al eliminar objetos contenidos

Antes de nada diré. ¿ No decimos que la propiedad Children devuelve una colección ?. ¿ Es realmente una colección o  es un array ?.  :roll: 
Aparenta ser más un array de controles, que no una colección de controles.. 8) 
[/quote]

Pero que busca boca eres :)

Si, es un array, sin duda, yo no me he leído ahora a mi mismo, suelo meter la pata en palabras simplemente por que se lo que pienso pero no lo expreso por escrito. Y si, soy un desastre con los conceptos, pero cuando programo y tengo una meta, suelo llegar a ella "como sea", así soy yo.

Mil disculpa por la cagada.

Nota: Tras leerte has escrito mucho pero al final no has respondido por código con el título de tu hilo "Eliminar un objeto de su contenedor padre", se que lo haces en alusión a mi hilo, pero no lo aclaras según tu forma de programa, chupate esa :) (supongo que entiendes que es broma y no lo veas como otros, que dicen de mi algo como que yo trato el foro como una verdulería, que curiosamente hay que leer bien el hilo para pensar quien es el verdulero y quien es el que compra verduras, en fin, lo que tengo claro es quien soy yo)

Aaadios


-----------------------------------
Shell
Domingo, 28 Junio 2020, 09:59

Re: Eliminar Un Objeto De Su Contenedor Padre
-----------------------------------
GambaFeliz:

[quote]
Nota: Tras leerte has escrito mucho pero al final no has respondido por código con el título de tu hilo "Eliminar un objeto de su contenedor padre", se que lo haces en alusión a mi hilo, pero no lo aclaras según tu forma de programa, chupate esa (supongo que entiendes que es broma y no lo veas como otros, que dicen de mi algo como que yo trato el foro como una verdulería, que curiosamente hay que leer bien el hilo para pensar quien es el verdulero y quien es el que compra verduras, en fin, lo que tengo claro es quien soy yo)
[/quote]

Ah, es que me gustó mas hacerlo invisible el botón.  :roll: 

Eliminar el botón del contenedor era más sencillo. Aunque al principio también me costó entenderlo.
Me encontré el problema de los indices, como van cambiando según eliminas controles.

El recorrido es obligatorio y más lento al ser un array.  Pero...encontré otra forma mejor si quieres eliminar. :-)

[code linenumbers=false syntax=gambas]
Const BOTONESXANCHO As Integer = 5
Const BOTONESXALTO As Integer = 5

Public Sub Form_Open()
  
  Dim unboton As Button
  Dim i As Integer    
  Dim anchoboton As Integer
  Dim altoboton As Integer
  
  Me.Title = "Eliminar objeto del Panel"
  With Panel1
    .Arrangement = Arrange.Column
    .Expand = True   
  End With
  
  anchoboton = Me.w / BOTONESXANCHO
  altoboton = Me.H / BOTONESXALTO
  
  For i = 0 To BOTONESXANCHO * BOTONESXALTO - 1
    unboton = New Button(Panel1) As "Observador"    
    With unboton
      .W = anchoboton
      .H = altoboton      
      .Text = "Botón " & (i + 1)      
      .Tooltip = "Haz click en mi"
    End With
    
  Next  
  
End


Public Sub Observador_Click()
  
  'Con esto es suficiente. Tampoco se necesita usar la propiedad tag
  Last.Delete
  
End

Public Sub Form_Resize()
  
  Dim unboton As Button
  
  'Ajustamos el tamño de todos los botones al cambiar el tamaño del formulario
  For Each unboton In Panel1.Children 
    With unboton
      .W = Me.w / BOTONESXANCHO
      .H = Me.H / BOTONESXALTO
    End With 
  Next
  
End
[/code]

Subo una modificación del código. He abreviado más el código.

Comenta si este te parece más acorde.  :wink: 

¿ Te interesa más eliminar con un indice ?.

Saludos


-----------------------------------
gambafeliz
Domingo, 28 Junio 2020, 19:58

Re: Eliminar Un Objeto De Su Contenedor Padre
-----------------------------------
Ya Shell pero tu caso es para controles que son visibles para el usuario pero mi caso y quizás no te lo he dicho en ninguna para es para controles no visibles para el usuario que es fundamental que el programador los destruya por completo para crearlos nuevamente según su necesidad, algo como creo 2 controles y después los destruyo para volverlo a crear 2 o 4 nuevos con el name 1, 2 o 1, 2, 3, 4

Son cosas que necesitaba, pero que mi sorpresa fue cuando intentaba destruirlos y noté que cuando usaba For-Next para recorrerlo y destruía el primero creado pues no podía destruir el segundo por que iba con un orden de indice incrementado. Y es cuando noté que debía destruirlo con For-Next Step y después todo funcionó.

Y como bien decías efectivamente esto me ocurría por que era un array de controles.

Muchas gracias por tu extenso aporte.

Aaadios :)


-----------------------------------
Shell
Lunes, 29 Junio 2020, 11:33

Re: Eliminar Un Objeto De Su Contenedor Padre
-----------------------------------
GambaFeliz:

Cuando tu veas que tienes un problema con un código y no quieres subir todo un proyecto, por ser algo personal, por motivos distintos,
son proyectos que en principio pues son tuyos y por otra parte no a todos nos valen los proyectos de otros usuarios.
Imagina subir todo un proyecto enorme, no es necesario para centrarnos en una parte determinada.

Intenta subir un pequeño código donde demuestras el error para que podamos testearlo todos los que podamos ayudarte 
sin ser todo el proyecto,  solo una forma de demostrar el error. Esto vale para todos nosotros.

Por otra parte ya no es solo por el error y su solución, otros compañeros pueden darte una mejora que te puede interesar.
Si tu conoces una forma de hacer las cosas, otro usuario puede enseñarte otra posibilidad de llegar al mismo
lugar. :-)

A mi me gusta ayudar, ya que a la vez que ayudo , aprendo.
Mi problema es que me anticipo mucho, eso me motiva en parte, pero debería de hacerlo de otra forma,
tomarlo con más tranquilidad...soy muy inquieto... :roll: 

Saludos


