Shordi   04-07-2023, 11:48
#1
Tengamos este formulario.
[Imagen: Wtnce9d.png]
Tiene dos gridviews, tres Label y un Listbox.
Al pulsar el botón Colorize quiero que los gridviews y los labels cambien de colores para lo que hacemos una función que lo haga y que descienda recursivamente por el árbol de contenedores:
Código:
Private Sub ColorizeGrid(ctrl As Object)  
 
  Dim o As Object
  Dim sClass As String
 
  sClass = Object.Class(ctrl).Name
  If sClass = "GridView" Or If sClass = "Label" Then ' Si es Gridview o Label cambiamos los colores
    ctrl.Background = Color.lightGray
    ctrl.Foreground = Color.DarkRed
  Endif  
  If Object.Class(ctrl).Exist("Children") And If ctrl.Children.count > 0 Then 'Si es un contenedor, recursivo a sus hijos
    For Each o In ctrl.Children
      ColorizeGrid(o)
    Next
  Endif
 
End


Lo pulsamos y obtenemos ésto:
[Imagen: o69uCEs.png]

¡Oh, sorpresa! el ListBox también ha cambiado de colores. ¿Por qué? Pues porque internamente contiene un Gridview al que accedemos mediante la propiedad Children.
Esto pasaría con un treeview, o con cualquier objeto que contenga gridviews o Labels, etc.

¿A alguien se le ocurre cómo prevenir ésto y que sólo se coloreen los controles que deseamos?

Venga, a estrujarse el coco, que es una tontería pero me lleva loco.

Adjunto el proyectito de prueba.

Saludos
Archivos adjuntos
.gz
Containers_War-0.0.1.tar.gz (Tamaño: 12.42 KB Descargas: 5)
Última modificación: 04-07-2023, 11:49 por Shordi.

No podemos regresar
Harpo   04-07-2023, 14:40
#2
Así a bote pronto....
Código:
Private Sub ColorizeGrid(ctrl As Object)

  Dim o As Object
  Dim sClass As String

  sClass = Object.Class(ctrl).Name
  If (sClass = "GridView" Or sClass = "Label") And If Not Object.Is(ctrl.Parent, "Usercontrol") Then ' Si es Gridview o Label cambiamos los colores
    ctrl.Background = Color.lightGray
    ctrl.Foreground = Color.DarkRed
  Endif
  If Object.Class(ctrl).Exist("Children") And If ctrl.Children.count > 0 Then 'Si es un contenedor, recursivo a sus hijos
    For Each o In ctrl.Children
      ColorizeGrid(o)
    Next
  Endif
End

Elimina aquellos GridView o Label embebidos en un Usercontrol. Se puede añadir los que estén en un Usercontainer.

[Imagen: BonYzvt.png]

Habría que probarlo con otros controles.
Un saludo, Harpo.
tercoide   04-07-2023, 17:42
#3
Para mi la solución ideal seria dejar un "rastro" ya sea en el Name, en el Group o en el Tag para sean aplicables (o no) al cambio de "skin" del programa.

"Es mejor saber todo de muy poco que muy poco de todo" - anonimo
Shell   04-07-2023, 19:34
#4
Aun no me he enterado.

¿ Entonces no quieres que se coloreé el ListBox ?. Rolleyes

Código:
...
 If Object.Class(ctrl).Exist("Children") And If ctrl.Children.count > 0 And sClass <> "ListBox" Then 'Si es un contenedor, recursivo a sus hijos
    For Each o In ctrl.Children
      ColorizeGrid(o)
    Next
  Endif
...

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Shordi   04-07-2023, 19:46
#5
Cita:¿ Entonces no quieres que se coloreé el ListBox ?.
No exactamente: No quiero que se coloree ningún control contenido en un control que no sea un contenedor... no sé si me explico. Listbox contiene un gridview, pero Listbox mismo no es un contenedor de controles "per se".
Cita:Para mi la solución ideal seria dejar un "rastro" ya sea en el Name, en el Group o en el Tag para sean aplicables (o no) al cambio de "skin" del programa.
Así no fallas, pero no te vale para cualquier control "normal", que no lleve ese Tag, o Nombre o lo que sea. Además te obliga a, en tiempo de diseño, ir recordando y colocando qué tag debe tener qué control, etc. y yo estoy buscando algo más universal.

La solución de Harpo:
Código:
[code]
Se acerca a lo que busco y da ciertas pistas que paso a comprobar.

Ya os contaré.

Saludos.
Última modificación: 04-07-2023, 19:47 por Shordi.

No podemos regresar
Harpo   04-07-2023, 20:12
#6
He hecho la siguiente prueba:
  • Añadir dos nuevas clases: GridView y Label.
  • En ambas he metido el siguiente código:
[Imagen: m4MCrqV.png]
  • En el IDE aparece la propiedad Colorize, la coloco a True en todos los controles.
[Imagen: oO4Bua2.png]

Modifico código:
Código:
Private Sub ColorizeGrid(ctrl As Object)

  Dim o As Object
  Dim sClass As String

  sClass = Object.Class(ctrl).Name
  If sClass = "GridView" Or If sClass = "Label" Then ' Si es Gridview o Label cambiamos los colores
    If Not Object.GetProperty(ctrl, "Colorize") Then Return     ''Nueva propiedad
    ctrl.Background = Color.lightGray
    ctrl.Foreground = Color.DarkRed
  Endif
  If Object.Class(ctrl).Exist("Children") And If ctrl.Children.count > 0 Then 'Si es un contenedor, recursivo a sus hijos
    For Each o In ctrl.Children
      ColorizeGrid(o)
    Next
  Endif
End

Resultado:
[Imagen: 100Hn22.png]

Es otra opción, un saludo.
Harpo.

Por cierto, el GridView embebido en el ListBox también tiene la propiedad Colorize....
Última modificación: 04-07-2023, 20:36 por Harpo.
cogier   05-07-2023, 19:19
#7
Aquí he utilizado la propiedad 'Tag'.
Archivos adjuntos
.gz
Containers_War_Charlie-0.0.1.tar.gz (Tamaño: 12.46 KB Descargas: 2)
tercoide   05-07-2023, 21:37
#8
La propiedad Tag es la forma adecuada de hacerlo. Realmente no cuesta nada dejar un rastro allí en tiempo de diseño, e incluso puede ser varios.

Cogier uso "ToCol" que abrevia To Colorize, pero puede dearse un Integer con uno de los bits que indique la colorizacion y los otros para distintos usos.

"Es mejor saber todo de muy poco que muy poco de todo" - anonimo
Shordi   06-07-2023, 08:02
#9
Gracias a todos. Veo que os interesa el tema. La propiedad Tag no se adapta muy bien a lo que necesito pero, claro, no sabéis muy bien qué estoy haciendo. A ver si puedo subir un vídeo y el proyecto al gitlab esta mañana o, a lo más tardar, mañana.


Saludos

No podemos regresar
  
Usuarios navegando en este tema: 3 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.