Tengo un grupo de casillas de verificación, para ser precisos, hay 3 casillas. Funciona para mí cuando uso la declaración if, pero me pregunto si hay una manera de recorrer las casillas de verificación y asignar valores de enumeración cuando una casilla está marcada o más.
El código se ve así:
if (chkTomato.Checked && !chkLettuce.Checked && !chkCarrot.Checked) { cart.VegChosen = Veggies.Tomato; } else if (!chkTomato.Checked && chkLecctuce.Checked && !chkCarrot.Checked) { cart.VegChosen = Veggies.Lecctuce; } else if (!chkTomato.Checked && !chkLecctuce.Checked && chkCarrot.Checked) { cart.VegChosen = Veggies.Carrot; } else if (chkTomato.Checked && chkLettuce.Checked && chkCarrot.Checked) { cart.VegChosen = Veggies.All; } else if (chkTomato.Checked && chkLettuce.Checked && !chkCarrot.Checked) { cart.VegChosen = Veggies.TomatoAndLettuce; } else if (chkTomato.Checked && !chkLettuce.Checked && chkCarrot.Checked) { cart.VegChosen = Veggies.TomatoAndCarrot; } else if (!chkTomato.Checked && chkLettuce.Checked && chkCarrot.Checked) { cart.VegChosen = Veggies.LettuceAndCarrot; } else { cart.VegChosen = Veggies.None; }Quiero encontrar una manera de hacer un bucle en caso de que haya más de 3 casillas de verificación, la declaración if sería muy larga.
¡Gracias!
Si bien esto no usa bucles, espero que esto sea lo que está tratando de lograr. Suponiendo que su enumeración se declare así:
[Flags] public enum Veggies { None = 0, Tomato = 1, Lettuce = 2, Carrot = 4, TomatoAndLettuce = Tomato | Lettuce, TomatoAndCarrot = Tomato | Carrot, LettuceAndCarrot = Lettuce | Carrot, All = Tomato | Lettuce | Carrot }Entonces debería poder usar un enfoque bit a bit similar para asignar valores:
Veggies selectedVeggies = Veggies.None; if (chkTomato.Checked) { selectedVeggies = selectedVeggies | Veggies.Tomato; } if (chkLettuce.Checked) { selectedVeggies = selectedVeggies | Veggies.Lettuce; } if (chkCarrot.Checked) { selectedVeggies = selectedVeggies | Veggies.Carrot; } cart.VegChosen = selectedVeggies;El resultado neto de esto será el mismo que su conjunto actual de declaraciones if. La razón por la que usamos 1, 2, 4, etc. para los valores de enumeración es porque no se superponen entre ellos cuando se representan en binario (1 es 001, 2 es 010, 4 es 100, etc.) por lo que ese bit específico puede solo identifique ese valor de enumeración.
También tenga en cuenta que declaraciones como TomatoAndLettuce y TomatoAndCarrot quizás también sean innecesarias, ya que puede usar Enum.HasFlag() .
Por ejemplo:
var selectedVeggies = Veggies.Tomato | Veggies.Carrot; // or var selectedVeggies = Veggies.TomatoAndCarrot; // effectively the same as above if (selectedVeggies.HasFlag(Veggies.Tomato)) { cart.Add(new Tomato()); } if (selectedVeggies.HasFlag(Veggies.Carrot)) { cart.Add(new Carrot()); } // cart ends up with a Tomato and a CarrotLectura adicional: ¿Qué hace bit a bit o | hacer el operador?
Crea la enumeración así:
enum Veggies { Tomato = 1 << 0, Lettuce = 1 << 1, Carrot = 1 << 2, All = Tomato | Lettuce | Carrot } Esto hace que el valor de Veggies.Tomato = 1 que es 0000 0001 en bits, Veggies.Lettuce = 2 que es 0000 0010 y Veggies.Carrot = 4 que es 0000 0100 .
Es importante tener los valores de enumeración como 1 desplazados en bits (potencias de 2) para que pueda combinar dos valores de enumeración más tarde como un int como lo hice con Veggies.All , que es 0000 0111 .
Cambie VegChosen a un int, luego simplemente cambie su código a algo como esto bit a bit, o el valor de enumeración en VegChosen int:
cart.VegChosen = 0; if(chkTomato.Checked) cart.VegChosen |= Veggies.Tomato; if(chkLettuce.Checked) cart.VegChosen |= Veggies.Lettuce; if(chkCarrot.Checked) cart.VegChosen |= Veggies.Carrot; Más tarde, si desea probar qué verduras se eligieron de cart.VegChosen .
if((cart.VegChosen & Veggies.Carrot) != 0) { //... cart.VegChosen contains Veggies.Carrot } if((cart.VegChosen & Veggies.Lettuce) != 0) { //... cart.VegChosen contains Veggies.Carrot } //etc Esto suele ser un 50% más rápido/más eficaz que Enum.HasFlag() porque HasFlag() contiene varias comprobaciones de cordura, pero si no está programando específicamente para el rendimiento, es mejor usar lo que es más fácil de usar y leer y en ese sentido Recomendaría la respuesta de Llama.
Una vez que implementó la respuesta de Llamas de hacer una enumeración de banderas, puede poner todas sus casillas de verificación en un cuadro de grupo y hacer esto:
var veg = Veggies.None: groupbox.Controls .OfType<CheckBox>() .Where(c => c.Checked) .ToList() .ForEach(c => veg |= Enum.Parse<Veggies>(c.Name[3..]));Luego, todo lo que tiene que hacer es agregar más miembros de la enumeración y agregar más casillas de verificación donde el nombre de la casilla de verificación sea como "chkXXX", donde xxx es el nombre del miembro de la enumeración.
Esta es una construcción en bucle: obtiene todos los controles en el cuadro de grupo y filtra solo aquellos del tipo casilla de verificación, luego los reduce a solo casillas de verificación marcadas. Convierte esto en una lista (para que podamos foreach, porque foreach es una lista, no una cosa de LINQ). Foreach visitará cada casilla de verificación y preguntará si está marcada, O el valor de enumeración de las banderas existentes con el resultado de analizar el nombre de la casilla de verificación (quitando los primeros 3 caracteres) a Veggies. Al final, su variable de veg representará todas las casillas de verificación que se marcaron
Tenga en cuenta que el uso de rangos e incluso Enum.Parse<T> requería una versión bastante moderna de C#; si está ejecutando una versión que no admite rangos, puede usar Substring(3). Debe asegurarse de que todos los nombres de sus casillas de verificación estén bien alineados con sus nombres de enumeración. Si realmente quiere obtener un truco, puede crear sus casillas de verificación dinámicamente enumerando el Enum y colocando el valor de la enumeración como la etiqueta de la casilla de verificación cuando agrega el control al formulario (dinámicamente, en posiciones crecientes) de esta manera su formulario simplemente se adaptará automáticamente a independientemente de cuántos miembros de enumeración tenga