Guardar y Leer un valor de CheckBoxList

Fecha: 30/Nov/2004 (19/11/2004)
Autor: Marco Padierna,
[email protected]

 


1. El problema.

Es común en una aplicación tener que guardar una o varias selecciones múltiples, por ejemplo:

"Equipo de oficina que opera: [x] PC, [ ] Máquina de escribir, [x] Calculadora, [ ] Otro".

Una solución no muy elegante consiste en asignar un campo para cada opción, pero esto compromete el diseño de la base de datos y hace difícil el mantenimiento. Pensemos en 6 variables, cada una con 5 opciones. Esto nos daría 30 campos... Lo ideal sería guardar la combinación de opciones seleccionadas para cada variable en un solo campo.

NET ofrece el control CheckBoxList, pero en la documentación ("escasa como dientes de gallina") no hay ningún ejemplo de como guardar y leer en un solo valor todas las combinaciones de opciones seleccionadas. A lo sumo, explica que hay que revisar el valor Selected de cada item... y luego?

2. La solución.

El quid consiste en hacer un poco de matemáticas. Es sabido que se puede representar cualquier número entero con sumas de potencias de 2 ( 2^0=1, 2^1=2...). Yo no soy matemático, así que explicaré esto más para mi propia claridad: Para representar el número 5, se suma 2^0 + 2^2, cierto? (nos hemos saltado la potencia 1)

Esto nos permite desarrollar un algoritmo: podemos recorrer la colección de items de un checkbox para verificar si están seleccionados, si un item cualquiera está seleccionado, elevamos 2 a la potencia de su índice y lo sumamos a un acumulador. Ese valor es que se almacenará en el campo.

' calcular el valor y devolverlo 
For i = 0 To ct.Items.Count - 1 
    If ct.Items(i).Selected Then 
        v = v + (2 ^ i) 
    End If 
Next 
DoCheckBoxes = v

Hasta aquí todo funciona bien. Ahora, para mostrar las casillas, se recorre la colección de items del control. Para cada índice, se eleva 2 a la potencia del índice (le llamaremos J) y se hace una comparación de bits con el operador AND, entre el número J y el valor total.

If j = (v And j) Then

Si la comparación equivale al número J, entonces el valor total contiene al número J, por lo tanto activamos el item correspondiente. Difícil? no tanto, véase el código.

For i = 0 To ct.Items.Count - 1
    j = 2 ^ i 
    If j = (v And j) Then            ' v es el valor total almacenado
        ct.Items(i).Selected = True 
    Else
        ct.Items(i).Selected = False 
    End If 
Next

 

Para llamar a la función, se hace lo siguiente:

 

' para guardar el resultado en una variable, llamada m_Equipo:
m_Equipo = DoCheckBoxes("MyCheckBoxList", False, 0)
' para mostrar las opciones elegidas:
Dim m_Equipo As Integer = 31
DoCheckBoxes("MyCheckBoxList", True, m_Equipo)

 

Queda de tarea diseñar un componente que encapsule la funcionalidad. Alteren y transformen!
Se anexa una página con la demostración.


ir al índice

Fichero con el código de ejemplo: mpadierna_DoCheckBoxes.zip - 4 KB