El misterioso caso del CheckedListBox y el DataSource perdido
Me encuentro trabajando en un proyecto en que por necesidades del guión, me veo obligado a utilizar un control de tipo CheckedListBox.
Hasta aquí, nada anormal en la necesidad solicitada… nada anormal a excepción del Intellisense de Visual Studio 2008, herramienta de marras que utilizo para tal fin, aunque he revisado que el comportamiento se repite en Visual Studio 2010 Beta 2 y versiones anteriores.
El caso es que cuando ya tengo mis datos de acuerdo a List<objeto> y trato de pasárselo al control CheckedListBox, me doy cuenta de que Intellisense no ve el tan querido DataSource.
Por un momento pienso… «es imposible que a la gente de Microsoft se le haya pasado esto por alto.«.
Por otro lado pienso… «si se les ha pasado por alto, tendré que hacerme un bucle para recorrer la colección e ir agregando cada elemento uno a uno…, un rollo, pero al menos solventaría el problema.«.
No obstante, uno que es más desconfiado que nada y más terco aún, mira y remira la primera de las opciones y piensa… «debe haber alguna forma…«, así que me pongo a buscar y lo primero que hago (porque no me creo lo que dice Intellisense) es mirar el visor de clases y objetos de Visual Studio 2008 y mirar allí la clase System.Windows.Forms.CheckedListBox.
Allí sí encuentro varias propiedades ocultas,… entre ellas la propiedad DataSource, DisplayMember y ValueMember, así que sí, están ahí.
Además, es lógico pensar que deberían estar ya que el control CheckedListBox hereda de ListControl (que implementa los miembros comunes de los controles ListBox y ComboBox), y que a su vez hereda de Control. Las propiedades DataSource, DisplayMember y ValueMember están por ahí gracias a la herencia para deleite y disfrute nuestro.
Así que… aunque no aparezca en el Intellisense… que no decaiga la fiesta… porqué… ¿podemos usarlo?.
Pues sí, así es.
Y para muestra un botón.
Arranco con una aplicación Windows escrita en C# y una clase que no merece mayor consideración que el propio código:
{
public string Code;
public string Name;
public Product(string code, string name)
{
this.Code = code;
this.Name = name;
}
public override string ToString()
{
return this.Code + «t» + this.Name;
}
}
En el formulario he insetado un control Button y un control CheckedListBox.
Dentro del formulario, he agregado el siguiente código en lo que al evento MainForm_Load se refiere:
{
Product product;
List<Product> productsCollection = new List<Product>();
product = new Product();
product.Code = «A01»;
product.Name = «Naranjas»;
productsCollection.Add(product);
product = new Product();
product.Code = «A02»;
product.Name = «Peras»;
productsCollection.Add(product);
this.checkedListBox1.DataSource = productsCollection.ToList();
this.checkedListBox1.DisplayMember = «Code»;
this.checkedListBox1.ValueMember = «»;
}
Finalmente y en el control Button, he establecido un sencillo mecanismo para extraer aquellos elementos que hemos seleccionado:
{
foreach (var item in this.checkedListBox1.CheckedItems)
{
Product product = (Product)(item);
MessageBox.Show(product.Code + Environment.NewLine + product.Name);
}
}
Como podemos ver en este ejemplo, el control CheckedListBox no nos muestra en Visual Studio y «gracias» al Intellisense las propiedades DataSource, DisplayMember y ValueMember, sin embargo, están ahí y las podemos utilizar perfectamente.
Aún y así, hubiera sido un detalle que el control tuviera la posibilidad de chequear o deschequear una fila de datos del control a partir de un valor (true/false) pasado como parámetro, pero eso es motivo de otro estudio diferente que no viene al caso.
7 Responsesso far
Hola
Ya que lo mencionas, a mi me ha pasado varias veces en otros controles y con otras propiedades, creo que es una pulga del intellisence.
Y eso que dice, si se puede hacer,yo lo he hecho manualmente, seria algo mas o menos asi:
FrmDistri.ListaPedidos.Items.Add(dgvRow.Cells(0).Value, True)
Supongo que si el dataset, trae un campo bit, el lo va a marcar.
Saludos
Felipe
El motivo para que no aparezca la propiedad en el IntelliSense es que esta decorada con el atributo EditorBrowsableAttribute
«EditorBrowsableAttribute is a hint to a designer indicating whether a property or method is to be displayed. You can use this type in a visual designer or text editor to determine what is visible to the user. For example, the IntelliSense engine in Visual Studio uses this attribute to determine whether to show a property or method.»
Muchas gracias David.
Justamente por eso no se ve en el intellisense… por tener EditorBrowsable deshabilitada.
He ido a Reflector (sé que debería haberlo hecho antes) y allí he encontrado esto que comentas:
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
public object DataSource
{
get
{
return base.DataSource;
}
set
{
base.DataSource = value;
}
}
Muchas gracias por la aclaración.
Ahora sabemos porqué no aparece en el Intellisense… sin embargo… lo bueno es que está ahí.
Un saludo y a ver si en el próximo CodeCamp nos vemos (aunque para este pasado según he visto había obligaciones mayores). 🙂
Jorge
@Felipe,
eso demuestra y más con lo comentado por David, que a veces antes de desesperarnos podemos ir a herramientas tipo Reflector o el visor de objetos de VS y buscar los detalles.
Hay muchos y a veces nos pueden incluso salvar la vida. 🙂
Gracias por comentar.
Jorge
Hecho!! 🙂
Saludos
tio, disculpa la ignorancia, pero donde veo esto? [EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
@jaime.
Hola Jaime, gracias por preguntar.
Esto yo lo veo con Reflector. Supongo que conocerás la herramienta (gratuita). La encontrarás en este enlace (por si no la tienes):
http://www.red-gate.com/products/reflector/