20 enero 2006

Aprendemos a mostrar listados

Estamos comenzando a mostrar listados en pantalla. De primera mano conseguimos conectar un DataGridView con una colección de objetos de negocio mediante un BindingSource que hace de puente (aunque no es necesario ese puente ya que un IList puede usarse como DataSource). Comentario al canto: para conectar controles individuales (de una ficha de detalles) con propiedades de un objeto de negocio sí necesitamos usar un BindingSource intermedio, ya que el objeto de negocio en sí no vale como DataSource. En cambio, si el objeto de negocio está contenido (sólo o acompañado) en una colección, dicha colección puede ser un DataSource. Pero ojito con todo esto: esta conexión directa puede ser suficiente en algunos casos, pero no propaga cambios desde el negocio, me explico: se actualiza el control a partir del objeto de negocio, manualmente, y los cambios en los controles son realizados automáticamente en el negocio; pero si se modifica el objeto por código, el control no es actualizado automáticamente. Para conseguir esto, son necesarias 2 cosas: que el objeto de negocio implemente INotifyPropertyChanged disparando un evento en cada Set, y que los objetos de negocio sean contenidos en una BindingList para que procese esos eventos hacia arriba (hacia el DataGridView). No sé si cualquier IList procesa esos eventos, pero creo que no porque si no no tendría sentido que existiera BindingList. Está pendiente de probar esto.
Uno de los ejemplos (buscado por Caña,
DataGridView App using BackgroundWorker for Async Data Load de Mark Rideout) nos servirá para realizar la carga asíncronamente, en segundo plano. En el ejemplo, se trabaja sobre una BindingList que va creciendo leyendo archivos del disco duro, lo que refuerza la teoría de que nuestras colecciones de objetos de negocio deben implementar BindingList.
Por último, investigando en otra dirección: la configuración automática del DataGridView a partir de metadatos del objeto de negocio. Una primera aproximación, asignar el BindingSource directamente al DataGridView en tiempo de ejecución, funciona si tenemos activo el atributo AutoGenerateColumns del grid, pero muestra todas las propiedades (no nos permite seleccionar). Hemos encontrado un ejemplo bastante completo, de nuevo usando BindingList (la panacea), en este caso heredando de dicha clase para personalizar la lista de columnas que se ofrece. Esto nos permite crear vistas personalizadas de las clases de negocio, mostrando o ocultando ciertas columnas. Además aprendemos a utilizar el atributo Browsable para evitar que la propiedad Id se vea nunca. Y también descubrimos el atributo DisplayName para poner un nombre de columna a cada propiedad (que también puede usarse para los nombres de las etiquetas en los formularios de detalles). Sólo hay una cuestión abierta: al cargar automáticamente las propiedades como columnas, las devuelve en un orden aleatorio, no en el que están escritas en la clase. La documentación dice que esto es así (incluso puede cambiar entre 2 llamadas a GetProperties), que no puede hacerse nada para solucionarlo. La opción de incluir más metainformación con el orden de las propiedades en el objeto de negocio es fea, ya que para ordenar tenemos que numerar las propiedades, y esto dificulta la inserción de nuevas propiedades. Así que de momentos ignoramos este problema, ya que con las vistas del ejemplo anterior sí podemos definir en qué orden se verán las columnas.
Por último, y volviendo al DataGridView, un capítulo de ejemplo donde se enseña a configurar su apariencia. Y una pregunta al aire: en VS2003, el DataGrid tenía la posibilidad de cambiar de estilos mediante
DataGridTableStyle; parece que no hay nada similar para el DataGridView de VS2005. ¿Cómo se consigue esa funcionalidad? ¿O es que en Microsoft andan como los cangrejos?

1 Comments:

Blogger Pablo said...

Más allá de los listados de una única clase de negocio, hay que pensar después en las propiedades que son otros objetos de negocio, como el cliente de un albarán. Esta posibilidad es algo que debería ofrecer también nuestro DataSource, nuestra vista similar a la que extenderemos de BindingListView (formando parte de la colección o como objeto aparte), de forma que se pueda añadir una propiedad como Cliente (y devolvernos su ToString) o bien añadir un Cliente.Nombre, o un Cliente.DireccionPpal.Localidad que se obtenga navegando por los objetos componentes del registro actual. Seguiremos estudiando el caso, y planteando soluciones...

30 enero, 2006 21:45  

Publicar un comentario

<< Home