Ir al contenido principal

[WinForms] Group-CheckBox

Introducción:

En muchas ocasiones nos hemos visto en la necesidad de usar CheckBox en lugar de RadioButton por el simple hecho de que el CheckBox lo podes colocar en cualquier parte de nuestro formulario a diferencia del RadioButton que ya por el simple hecho de estar dentro de un contenedor hace un poco difícil usarlo con liberta, pero necesitamos que el CheckBox tenga la misma funcionalidad del RadioButton.

bueno, entonces vamos a darle al CheckBox la funcionalidad de poder trabajar en grupo, así que manos al teclado.

Primero, es crear un control que herede del control CheckBox cuyo código deberá ser el siguiente:

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Diagnostics;
5 using System.Linq;
6 using System.Text;
7 using System.Windows.Forms;
8
9 namespace TestClassLib
10 {
11 public partial class MyCheckBox : CheckBox
12 {
13 }
14 }


Luego agregar una propiedad que indicara el índice del grupo al cual pertenece el CheckBox.


1 private int _RadioGroupIndex = -1;
2 [DefaultValue(-1), Browsable(true), Description("Indice de agrupación")]
3 public int RadioGroupIndex
4 {
5 get
6 {
7 return _RadioGroupIndex;
8 }
9 set
10 {
11 if (value < -1)
12 throw new Exception("RadioGroupIndex invalido");
13 else
14 _RadioGroupIndex = value;
15 }
16 }


Sobre escribir el evento OnCheckedChanged


1 protected override void OnCheckedChanged(EventArgs e)
2 {
3 if (RadioGroupIndex >= 0)
4 {
5 List<MyCheckBox> groupList = FindRadioGroupList(FindForm());
6 if (groupList.Count == 0 && !DesignMode) this.Checked = true;
7 else if (groupList.Count() > 1)
8 {
9 foreach (MyCheckBox ckBox in groupList)
10 {
11 if (ckBox.Name == this.Name) continue;
12 ckBox.Checked = false;
13 }
14 }
15 }
16
17 base.OnCheckedChanged(e);
18 }

y para terminar creamos una función que se encargara de buscando en el formulario todos los controles MyCheckBox que tengan el mismo índice de grupo y que estén marcados.


1 private List<MyCheckBox> FindRadioGroupList(Control Container)
2 {
3 List<MyCheckBox> retRGList = new List<MyCheckBox>();
4 retRGList.AddRange(Container.Controls.OfType<MyCheckBox>().Where(pre => pre.RadioGroupIndex == this.RadioGroupIndex && pre.Checked).ToList());
5 foreach (Control cc in Container.Controls.OfType<Control>().Where(pre => pre.HasChildren))
6 retRGList.AddRange(FindRadioGroupList(cc));
7
8 return retRGList;
9 }

como resultado final tendremos nuestro propio CheckBox con la funcionalidad de poder ser agrupado y poderlos colocar en cualquier parte de nuestro formulario sin preocuparnos de estar aplicando una lógica de programación para cada CheckBox que querríamos que tenga este comportamiento, solo bastaría con asignarle al primer grupo de MyCheckBox en la Propiedad RadioGroupIndex = 0 y así sucesivamente como nos sea necesario.


 


[C#] Código completo:


1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Diagnostics;
5 using System.Linq;
6 using System.Text;
7 using System.Windows.Forms;
8 using System.Reflection;
9
10 namespace TestClassLib
11 {
12 public partial class MyCheckBox : CheckBox
13 {
14 private int _RadioGroupIndex = -1;
15 [DefaultValue(-1), Browsable(true), Description("Indice de agrupación")]
16 public int RadioGroupIndex
17 {
18 get
19 {
20 return _RadioGroupIndex;
21 }
22 set
23 {
24 if (value < -1)
25 throw new Exception("RadioGroupIndex invalido");
26 else
27 _RadioGroupIndex = value;
28 }
29 }
30
31 public MyCheckBox()
32 {
33 }
34
35 protected override void OnCheckedChanged(EventArgs e)
36 {
37 if (RadioGroupIndex >= 0)
38 {
39 List<MyCheckBox> groupList = FindRadioGroupList(FindForm());
40 if (groupList.Count == 0 && !DesignMode) this.Checked = true;
41 else if (groupList.Count() > 1)
42 {
43 foreach (MyCheckBox ckBox in groupList)
44 {
45 if (ckBox.Name == this.Name) continue;
46 ckBox.Checked = false;
47 }
48 }
49 }
50
51 base.OnCheckedChanged(e);
52 }
53
54 private List<MyCheckBox> FindRadioGroupList(Control Container)
55 {
56 List<MyCheckBox> retRGList = new List<MyCheckBox>();
57 retRGList.AddRange(Container.Controls.OfType<MyCheckBox>().Where(pre => pre.RadioGroupIndex == this.RadioGroupIndex && pre.Checked).ToList());
58 foreach (Control cc in Container.Controls.OfType<Control>().Where(pre => pre.HasChildren))
59 retRGList.AddRange(FindRadioGroupList(cc));
60
61 return retRGList;
62 }
63 }
64 }
65

[VB] Código Completo:



1 Imports System.ComponentModel
2
3 Partial Public Class MyCheckBox
4 Inherits CheckBox
5
6 Dim _RadioGroupIndex As Integer = -1
7 <DefaultValue(-1), Browsable(True), Description("Indice de agrupación")> _
8 Public Property RadioGroupIndex() As Integer
9 Get
10 Return _RadioGroupIndex
11 End Get
12 Set(ByVal value As Integer)
13 If value < -1 Then
14 Throw New Exception("RadiogroudIndex Invalido.")
15 Else
16 _RadioGroupIndex = value
17 End If
18 End Set
19 End Property
20
21 Protected Overrides Sub OnCheckedChanged(ByVal e As System.EventArgs)
22 If RadioGroupIndex >= 0 Then
23 Dim groupList As List(Of MyCheckBox) = FindRadioGroupList(FindForm())
24 If groupList.Count = 0 And Not DesignMode Then
25 Me.Checked = True
26 ElseIf groupList.Count > 1 Then
27 For Each ckBox As MyCheckBox In groupList
28 If ckBox.Name = Me.Name Then
29 Continue For
30 End If
31 ckBox.Checked = False
32 Next
33 End If
34 End If
35 MyBase.OnCheckedChanged(e)
36 End Sub
37
38 Private Function FindRadioGroupList(ByRef Container As Control) As List(Of MyCheckBox)
39 Dim retRGList As List(Of MyCheckBox) = New List(Of MyCheckBox)
40 retRGList.AddRange(Container.Controls.OfType(Of MyCheckBox).Where(Function(pre) pre.RadioGroupIndex = Me.RadioGroupIndex And pre.Checked).ToList())
41 For Each cc As Control In Container.Controls.OfType(Of Control).Where(Function(pre) pre.HasChildren)
42 retRGList.AddRange(FindRadioGroupList(cc))
43 Next
44 Return retRGList
45 End Function
46
47 End Class
48


Bueno!!!!…. espero les pueda ser de utilidad este código y cualquier mejora que se le pueda hacer pues no duden en comentarla,


Hasta el próximo blog.

Comentarios

Entradas populares de este blog

NetBarControl

Actualización.
NetBarControl - Description Item Style (New)




NetBarControl (Outlook Bar) es uno de los controles que muchas veces buscamos para usar en nuestras aplicaciones, pero siempre encontramos en internet versiones pagables y tal vez no contamos con el presupuesto esperado como para comprar uno y las versiones gratis que se logran encontrar, pues como son gratis no implementan en su totalidad la funcionalidad que esperamos encontrar en un control de este tipo. Antes de comenzar a escribir este control dedique tiempo en buscar uno por internet que tuviera toda la funcionalidad o por lo menos una interfaz disponible en modo de diseño, pero, no logre encontrar uno, así que me propuse crearlo como a mí me gustaría que funcionara uno gratis y al final llegue a la conclusión de ¿Porque no hay uno completo, gratis y que incluya el código fuente? y la respuesta es:No es fácil, pero tampoco es cosa de otro mundo. Con esto no digo que otro programador no lo pueda hacer o que los ejemplos en…

ComboBox-MultiColumns

ComboBox-MultiColumns Update


Como bien sabemos el Set de Controles de Windows de .Net Framework incluye el control ComboBox pero este no soporta mostrar multiples columnas, en su lugar muestra una lista simple ya sea agregada manual mente usando la propiedad Items o según el origen de datos definido a traves de la propiedad DataSource, usando la propiedad DisplayMember para indicar la propiedad o campo a mostrar en la lista desplegable. Bien… la ventaja de los controles de .Net Framework es que los podes extender para mejorar su uso en nuestros desarrollos, en este caso extenderemos el Control ComboBox para reemplazar la lista desplegable por nuestra propia versión que mostrara “N” cantidad de columnas que necesitemos, para esto haremos uso de las siguientes clases ToolStripDropDown y ToolStripControlHost. En la ayuda de MSDN podemos encontrar un ejemplo sobre como usar la clase ToolStripDropDown para mostrar un TreeView. parte de este ejemplo lo he tomado para crear este Control ComboBo…

TextEditor

Este control nace a raíz de una pregunta en el foro de Visual Basic .Net, sobre como cambiar el borde de un TextBox a un borde personalizado y además andaba buscando cambiar la apariencia del control NetBarControl para poder aplicarle una nueva propiedad para cambiar el estilo. ejemplo:


Aun que esta imagen solo es un pre-formato de cómo funcionara el control NetBarControl, solo que me distraje creando este nuevo control TextEditor. Así que le echaré mano al terminado este nuevo control.







Bien, la idea inicial era solo agregar botones a un control TextBox, pero luego usando el Mozilla, al descargar unos archivos me percate de un control en la parte inferior de esta venta de descargar, aun que se suele ver mucho en las páginas Web, pero me llamo la atención aquí en el Mozilla y en el Window Live Messenger.


Entonces… me entro el gusano de la curiosidad, agregar la imagen luego de agregar los botones ya no era la parte difícil, la parte curiosa es mostrar el Texto como marca de agua, enco…