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 struct Product
{
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:
private void MainForm_Load(object sender, EventArgs e)
{
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:
private void button1_Click(object sender, EventArgs e)
{
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.