Guardar y Leer un valor de
CheckBoxList Fecha: 30/Nov/2004 (19/11/2004)
|
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 = vHasta 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) ThenSi 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.
Fichero con el código de ejemplo: mpadierna_DoCheckBoxes.zip - 4 KB