Probablemente el control ListBox es uno de los más importante en el diseño de cualquiera de nuestras aplicaciones y, de hecho, también es uno de los más completos. Tanto es así, que no es realista cubrir todas sus capacidades en una sola entrada de AprendeXojo. De hecho, en una entrada anterior ya vimos de qué modo podemos ordenar las columnas de un ListBox por el valor numérico de sus datos. En esta ocasión veremos de qué modo tan sencillo podemos crear listados jerárquicos.
Los listados jerárquicos son aquellos en los que podemos alternar filas de datos normales con aquellas que presentan un elemento gráfico —por lo general un triángulo— que al ser pulsado despliega la ‘rama’ de la fila seleccionada para mostrar los valores agrupados bajo dicha entrada y que, una vez que volvemos a pulsar sobre dicho elemento, repliega nuevamente los contenidos agrupados bajo dicha rama.
Por tanto, los listados jerárquicos son un excelente modo de presentar información agrupada bajo una misma categoría en nuestras aplicaciones, así como la forma habitual de presentar cualquier otro tipo de información jerarquizada en la típica estructura de árbol, tal y como ocurre por ejemplo a la hora de mostrar los archivos y directorios de nuestros dispositivos de almacenamiento. Por supuesto, podemos presentar varios niveles jerárquicos en nuestros ListBox, si bien a partir de cierto nivel probablemente deje de ser una interfaz útil o manejable.
Definir ListBox como jerárquico
Lo primero que debemos hacer para que nuestros controles ListBox puedan presentar y trabajar con información jerarquizada (esto es, filas capaces de desplegar y replegar datos agrupados), es definir la propiedad Hierarchical a true
. Esto es algo que podemos hacer desde código, por ejemplo utilizando el Manejador de Evento Open sobre la propia instancia del ListBox o, más sencillo, seleccionando la instancia del ListBox sobre el Editor de Diseño en el IDE de Xojo, activando el Inspector y cambiando a On el control de tipo switch Hierarchical bajo el apartado Behavior.
AddFolder, el método para crear ‘grupos’
El segundo aspecto que hemos de tener en cuenta es que hemos de emplear el método AddFolder del ListBox en vez de AddRow a la hora de añadir aquellas entradas que deban de tratarse por el control como filas jerárquicas; es decir, acompañadas de la pequeña pieza gráfica triangular de despliegue/repliegue de datos.
La forma en la que debas de utilizar AddFoder o AddRow dependerá de la lógica de tu aplicación, así como del modelo de datos que vayas a utilizar en cada caso. Es decir, quizá el ListBox presente únicamente un primer nivel cuyas filas serán todas de tipo desplegable (jerárquicas), o bien debas de alternar filas jerárquicas con filas de datos no desplegables.
Un aspecto importante de AddFolder es que añadirá la nueva entrada al final de las existentes, actuando únicamente sobre la primera de las columnas. ¿Y cómo puedes añadir entonces jerarquías anidadas? La respuesta se encuentra en el evento ExpandRow.
ExpandRow: añadir elementos al grupo
Cuando añades filas con AddFolder, y ejecutas la aplicación, verás que el control ListBox hace su trabajo cambiando las entradas entre los estados de desplegado y replegado cuando pulsamos sobre ellas. Ahora bien, para añadir los datos que han de presentarse cuando desplegamos una fila en concreto hemos de acudir al evento ExpandRow. Una vez que añadimos dicho evento a nuestra instancia de ListBox veremos que se pasa como argumento el número entero correspondiente a la fila sobre la que se ha pulsado; es decir, la fila desplegada. Y, de hecho, lo más probable es que utilicemos dicho valor para conocer en nuestro modelo de datos cuál es grupo de nuevas filas que hemos de añadir bajo la entrada seleccionada. Por lo general, puede ser el propio texto de la celda pulsada en el ListBox o bien cualquier otro dato que hayamos añadido previamente mediante CellTag.
En cualquier caso, será nuevamente en este evento cuando utilizaremos los métodos AddRow o AddFolder para añadir las nuevas celdas que han de aparecer bajo la entrada desplegada.
Una consideración especialmente interesante es que, si bien cuando aplicamos estos métodos directamente sobre la instancia de ListBox, las nuevas entradas se añaden al final del listado, cuando se utilizan en este evento será el propio ListBox quien se encargue de añadir las nuevas filas bajo la fila desplegada, facilitando así enormemente la programación y reduciendo la cantidad de código necesario.
ListBox jerárquico, en la práctica
Es el momento de poner en práctica lo visto hasta ahora. Ejecuta Xojo y crea un nuevo proyecto de tipo escritorio. A continuación sigue estos pasos:
- Selecciona el objeto
Window1
en el Navegador de Proyectos (la columna situada más a la izquierda en el IDE de Xojo). - Añade una instancia del control ListBox desde Library sobre la ventana Window1 mostrada en el Editor de Diseño.
- Selecciona la nueva instancia de ListBox,
ListBox1
y accede al Panel Inspector para poner enOn
la propiedadHierarchical
. También puedes aprovechar para anclar el control sobre los cuatro márgenes de la ventana.
Con esto habremos terminado con el diseño de nuestra interfaz de usuario. A continuación crearemos un modelo de datos para nuestra aplicación de ejemplo. Esto es, los datos que mostrará la instancia del ListBox en su primer nivel (todas ellas serán filas desplegables), así como cuando se despliegue cada una de las entradas:
- Selecciona el objeto
App
en el Navegador de Proyectos y añade una nueva propiedad. Con la nueva propiedad seleccionada, utiliza el panel Inspector para asignar los valrescontenidos
yDictionary
en los camposName
yType
, respectivamente. - A continuación, añade el evento Open al objeto App y añade el siguiente código en dicho evento. Será el encargado de crear el modelo de datos propiamente dicho:
dim primero() as string = Array("Uno", "Dos", "Tres", "Cuatro")
dim segundo() as string = Array("Cinco", "Seis", "Siete", "Ocho")
dim tercero() as string = Array("Nueve", "Diez", "Once", "Doce")
contenidos = New Dictionary("Primero":primero, "Segundo":segundo, "Tercero":tercero, "Cuarto":cuarto)
- Seleccionar ahora la instancia
ListBox1
en el Navegador de Proyectos y añade el eventoOpen
. Aquí es donde aprovecharemos para presentar nuestro control ListBox con las filas correspondientes a los primeros niveles de nuestra jerarquía. Introduce el siguiente código en el Editor de Código resultante:
dim elementos() as variant = app.contenidos.keys
for each item as string in elementos
me.addfolder item
next
Si ejecutas la aplicación de ejemplo en este punto comprobarás que puedes desplegar y replegar cada una de las entradas del ListBox pero no se muestran los datos asociados. Esto es lo que haremos a continuación.
- Con la instancia
ListBox1
seleccionada, añade en esta ocasión el manejador de evento ExpandRow, e introduce el siguiente código en el Editor de Código resultante:
dim elementos() as String = app.contenidos.Value(me.list(row))
for each item as string in elementos
me.AddRow item
next
Ejecuta de nuevo la aplicación y, en este caso, comprobarás como cada grupo muestra los elementos asociados y que, cuando repliegas cada una de las entradas estas desaparecen del listado correctamente sin necesidad de que debamos de encargarnos de escribir código adicional.
*Esta entrada ha sido escrita en Markdown y exportada como HTML para este blog con Snippery
[…] por ejemplo podremos reflejar en un ListBox todos los archivos visibles disponibles en la carpeta de Documentos mediante el siguiente fragmento […]
Pero que pasa si quisiéramos añadir un tercer y un cuarto nivel, como tendríamos que hacerle?
Saludos
Echa un vistazo al ejemplo “FileBrowser” que acompaña al IDE. Verás qué fácil resulta 😉