Personalizar el DataGrid para mostrar imágenes de Base de datosHeredar de DataGridColumnStyle para manejar imágenes
Fecha: 26/Mar/2006 (23/03/2006)
|
Trabajando con el DataGrid, me vi en la necesidad de mostrar imágenes traidas de la base de datos, y buscando por Internet encontré un ejemplo bueno pero revisando el código vi que usaba una propiedad un ImageList, obviamente las imágenes se jalaban de otro lado, pero yo quería que jalara directamente de la base de datos, en donde tenia una tabla con un campo de tipo image.
Al cargar los datos vi que mostraba los elementos usando internamente la función ToString() , porque para las imágenes mostraba “Matriz Byte[]” encontré que el método GetColumnValueAtRow obntiene el contenido real de la celda, entonces desarrolle una nueva clase heredera de DataGridColumnStyle para mostrar imágenes, llamada DataGridPictureBoxColumn para mantener el orden en relacion los demás estilos ya definidos en el sistema: DatGridBoolColumn y DatGridTextBoxColumn.
Empezamos entonces a crear la tabla, que para ahorrar tiempo lo haré en la base de datos llamada CRM (ya esta lista, pero pueden crear otra base de datos o usar una existente como pubs que viene en SQL Server 2000), llamada Customer (me gusta usar nombres en ingles, algo que a mis amigos de la universidad no les parece bien jejeje).
Comentarios sobre esta tabla:
EL campo City es int por que esta relacionado con otra tabla, pero para el ejemplo no es necesaria, asi que removí la referencia, esta tabla es de mi base de datos CRM.
El Id es autonumerico.
Los demas campos nos son necesarios pero están alli por que la tabla es de una base de datos de un proyecto en construccion “real”, pero solo nos interesa principalmente el campo Photo de tipo image
En el archivo Scripts.sql esta la tabla y los procedimientos almacenados necesarios para el ejemplo.
Creación del proyecto en Visual Studio.
Luego creamos un proyecto llamado Customers en Visual Studio .NET 2003
Y agregamos las clases DataGridColumnStyle, para poner alli los metodos que deben sobrescribirse pero que sin embargo no las usaremos (y tampoco se van a usar si hacemos otras clases de estilo de columna).
Y ahora si viene lo bueno: agregamos DataGridPictureBox, que hereda de nuestra clase DataGridColumnStyle e implementa los metodos:
// Devuelve el alto minimo de una fila int GetMinimumHeight() { } // Devuelve la altura preferida de una fila int GetPreferredHeight(Graphics g, object value) { } // Devuelve un System.Drawing.Size que contiene en tamaño preferido para la columna Size GetPreferredSize(Graphics g, object value) { } // Pinta la columna y tambien su contenido, en este caso, una imagen void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight) { }
El trabajo se hace en el metodo Paint() en donde obtenemos el contendio de la celda, como sabemos que es una secuencia de bytes lo almacenamos en una variable de tipo byte[], a continuación lo cargamos en un MemoryStream y por ultimo generamos la imagen con el método FromStream de la clase Image.
Luego creamos un formulario CustomerListForm para mostrar la lista de clientes registrados en el sistema, que básicamente consta de un Datagrid y dos botones: “Nuevo” y “Cerrar”, esta por demás decir que cosa hacen.
Ahora bien, llegado a este punto, siempre incluyo una clase llamada Program a todos mis proyectos, en donde pongo las propiedades globales a toda la aplicación y también la funcion Main(), en este caso pondremos aquí la clase que nos conectara con la base de datos: SqlClient, del espacio de nombres Hardworks.Data.SqlServer, del cual adjunto solo la DLL (el código de esta es muy extenso, y estaré preparado un artículo para otra colaboración).
Esta clase encapsula muchas funciones de System.Data.SqlClient y System.Data.OleDb y ofrece una interfaz más sencilla, en donde podemos recuperar objetos DataSet, DataTable y valores escalares.
En el constructor estático de la clase Program inicializamos la cadena de conexión, tan sencilla y orientada a objetos:
private static SqlClient mDatabase; mDatabase = new SqlClient(); mDatabase.ConnectionString.Catalog = "CRM"; mDatabase.ConnectionString.DataServer = "rkarl"; mDatabase.ConnectionString.UserName = "x86"; mDatabase.ConnectionString.Password = "x86";
Vale decir que debes cambiar aquí los valores para poder conectarse correctamente.
Para evitar ingresar nombres de usuario y contraseña, podemos usar también:
mDatabase.ConnectionString.IntegratedSecurity = IntegratedSecurity.SSPI;
Visualización del DataGrid con imagenes.
Ahora viene lo más importante para que se muestre correctamente la imagen: establecer los estilos de las columnas al DataGrid, esto lo hacemos en el evento Load del formulario, y para comodidad lo puse en una función aparte: SetColumnStyles() alli creamos los estilos para las columnas, y para la de tipo imagen instanciamos de la clase DataGridPictureBoxColumn y establecemos algunas propiedades mas como Size y SizeMode.
Veamos el programa ejecutandose, aquí ya ingrese algunos datos:
Y este es la ventana del formulario CustomerNewForm:
La manera en que guarda la imagen es parecida a la manera en que se carga la imagen de la base de datos.
Espero que les sea útil... y no se olviden de votar en PanoramaBox.
Sobre la DLL Hardworks.Data.dll espero sus comentarios al respecto… pronto les enviare un artículo y el código completo.
Saludos cordiales.
Richard Karl
Espacios de nombres usados en el código de este artículo:
System;
System.Data;
System.Drawing;
System.Windows.Forms;
(mio):
Hardworks.Data;
Hardworks.Data.SqlServer;
Fichero con el código de ejemplo: RichardKarl_DataGridConImagenes.zip - 73 KB
(MD5 checksum: [8B6CAFACD144E77A6DE012BC801C1F49])