Visual Basic Foro
Programación => Visual Basic .NET / C# => Mensaje iniciado por: coco en Febrero 06, 2014, 12:24:00 am
-
Buenas!
Como dice el titulo, quisiera saber como hacer para leer los datos leidos en una consulta a una DB MySQL a un ListView o algun equivalente de .NET (actualmente v4.0).
Tambien quiero saber si realmente conviene hacer este tipo de manejes (como en VB6 con el .DataSource y demas), o bien cargar los datos a mano (como en VB6 usando un Recordset, loopeando y agregando a un LV item por item).
Vamos a suponer que es la lista donde se cargan los usuarios de un lugar (donde ahora mismo hay 20k, pero estaria bueno implementarlo bien, como para cargar 100k sin problemas).
La idea principal es simplemente mostrar los usuarios, sin posiblidad de editarlos a priori (porque se van a terminar confundiendo los que usen el soft), asi que la edicion podria estar en otro form tranquilamente.
Inclusive se podria hacer que se muestre una miniatura de su foto, haciendo que las filas sean mas gruesas.
Pero sin desviarse tanto, yo quiero que esto no laguee nada, y que a su vez mantenga una cierta estetica.
Y si saben como hacer lo de las fotos, mejor!
Saludos!
-
Yo utilizo esto que encontre en solovb.net
http://www.solovb.net/index.php/2009/02/10/varias-formas-de-cargar-un-listview/ (http://www.solovb.net/index.php/2009/02/10/varias-formas-de-cargar-un-listview/)
http://www.solovb.net/index.php/tag/listview/ (http://www.solovb.net/index.php/tag/listview/)
Y para mostrar los usuarios yo los tengo asi:
(http://snag.gy/6lkxU.jpg)
-
Por lo que yo se (use hasta la versión 2.0) si SOLO vas a mostrar y nada más, no sirve de mucho los datasets tipados (los que generas con el asistente y diseñadores) porque eso es para para algún DataGrid con propiedades de edición.
Si vas a usarlo con ListView, tenes que usar la clase DataReader, que es más rápida porque es solo lectura y solo para adelante.
Peeeero, por más rapido que lo hagas un dataView (o algo así, un control nativo de .net) siempre mostrará los datos más rapido (y quizás más feo) que un ListView, a menos que experimentes con ObjectListView... pero ne eso no tengo experiencia :P
-
http://leandroascierto.com/foro/index.php?topic=2234.0
-
Bien. Yo creo que me quedo con el DataGridView.
Ahora estoy viendo como cargar una imagen (desde un blob) a una celda.
Por defecto el .NET me toma una columna de LONGBLOB como imagen. Pero si dicha columna tiene NULL (no hay imagen), me tira el iconito de error del IE6 (este -> (http://lh6.ggpht.com/_97t2cvMP3SQ/TTSxChZrQFI/AAAAAAAAATw/zIVYPjoQzgg/s800/broken_image.gif)).
Ahora bien, encontre en internet que se puede pintar la imagen en la celda, usando el "value" de dicha celda, en el evento CellPainting.
Pero esto indica que tengo que castear el Value a Byte[], convertirlo a un memorystream y pasarlo a un Image cada vez que el Grid necesita repintar esa fila.
Esto quedaria aproximadamente asi:
(http://snag.gy/ZqSfy.jpg)
Aca dejo el codigo que hice (usando conceptos que vi en internet)
private Image GetImageFromByteArray(byte[] bytes)
{
if (bytes.Length == 0)
return null;
try
{
MemoryStream mem = new MemoryStream(bytes, 0, bytes.Length);
return Image.FromStream(mem);
}
catch (Exception e)
{
return null;
}
}
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == -1)
return;
if (dataGridView1.Columns[e.ColumnIndex].Name == "photo")
{
Image img;
Point pt = new Point(e.CellBounds.Left, e.CellBounds.Top);
/* remove stupid error image */
e.Handled = true;
e.PaintBackground(e.CellBounds, true);
if (e.Value is DBNull)
return;
img = GetImageFromByteArray((Byte[])e.Value);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
if (img != null)
e.Graphics.DrawImage(img, e.CellBounds, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
}
}
Que otra forma existe de hacer esto?
Saludos.
-
Si mas no recuerdo el DataGridView tiene una clase que se llama CellFormatting que lo que hace como su nombre lo indica darle formato a la celda y cell.value le tiras la imagen convirtiendo de binario a imagen con los codigos de ejemplo si no utiliza estos:
Public Function BytesaImagen(ByVal bytes As Byte()) As Bitmap
Return CType(Bitmap.FromStream(New IO.MemoryStream(bytes)), Bitmap)
End Function
Public Function ImagenaBytes(ByVal vImagen As Bitmap) As Byte()
Dim vMemoria As New System.IO.MemoryStream
vImagen.Save(vMemoria, Imaging.ImageFormat.Bmp)
Dim outBytes(CInt(vMemoria.Length - 1)) As Byte
vMemoria.Seek(0, System.IO.SeekOrigin.Begin)
vMemoria.Read(outBytes, 0, CInt(vMemoria.Length))
Return outBytes
End Function
osea solo le das el value = BytesaImagen(DataReader("Cant"))
eso en teoria tendria que bastar.
-
Claro, eso es logico, pero yo no agrego item por item. Es decir, al enlazar el datasource, quedo desligado de la lectura item por item.
Como vos decis, en el evento CellFormatting cae el .Value (BLOB), pero ¿uno tiene que convertir el mismo .value a una imagen? (no le veo el sentido)
Y dicho evento, solo se llama al cargar los datos, verdad?
Ademas, dicha columna es del tipo DataGridViewImageColumn.
EDIT:
Aca lo tengo hecho.
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex == -1)
return;
if (((DataGridView)sender).Columns[e.ColumnIndex].Name.Equals("photo"))
{
e.FormattingApplied = true;
if (e.Value is DBNull)
e.Value = GestionSocios.Properties.Resources.generic_headshot;
else
e.Value = GetImageFromByteArray((Byte[])e.Value);
}
}
Ahora faltaria hacer un resize al e.Value, lo cual voy a indagar proximamente.
Igual no me convence a pleno, porque si bien se carga la imagen y todo, me da la sensacion que esto consume ram a lo pavote (cada vez que repinta y demas, tipo leak).
Para finalizar, me gustaria saber como hacer esto:
si tengo mi funcion GetImageFromByteArray, como podria hacer que pase "por referencia" un objeto Image, y que devuelva true o false segun si cargo o no la foto? (esto esta mas orientado a C o C++ y no es tan OOP, pero bueno. Sino indiquenme de que forma podria atrapar esos errores)
Saludos!
-
Ojala esto te sirva
http://ltuttini.blogspot.com/2011/02/winforms-edicion-empleados-grabar.html (http://ltuttini.blogspot.com/2011/02/winforms-edicion-empleados-grabar.html)
aqui un ejemplo del mismo en vb.net http://www.ltuttini.com.ar/blogfiles/WinForms/EdicionEmpleado/[vb.net]ListaEmpleados.zip
si lo vas hacer por CellFormatting ten cuidado con el parpadeo del grid
agregalo un DoubleBuffered = True para evitar el parpadeo
gracias