none
Ayuda..Cargar imágenes desde sql a un datagrid wpf RRS feed

  • Pregunta

  • Bueno primero que nada soy nuevo qui en el foro así como también en wpf, en segunda yo se que ya han echo esa pregunta aquí en el foro con muy buenas respuestas algunas que recuerdo de David pero yo lo que quiero es guardar la ruta de la imagen en la bd y al mismo tiempo guárdalas en una carpeta del proyecto para después mostrarlas en un datagrid o listview..me gustaria una idea de como hacerlo o algún ejemplo Gracias!!
    miércoles, 9 de mayo de 2012 18:10

Todas las respuestas

  • Hola Gilberto.

    ¿por donde vas?, ¿te has quedado atascado en algun sitio?.

    Yo lo que haria seria crear una tabla en BBDD con un ID, rutaImagen, descripcionImagen (por ejemplo), en ella puedes guardar la ruta de la imagen, pero como la ruta puede variar de una instalacion a otra, deberias de guardar una ruta relativa a la aplicacion y en la aplicacion hacer uso de la ruta relativa donde se guardaran las imagenes por ejemplo con la siguiente linea:

    System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase), "carpeta\\imagen.png");

    si me cuentas por donde vas puedo ir ayudandote con lo que necesites.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    lunes, 14 de mayo de 2012 18:55
  • Eso es exactamente lo que quiero hacer, ya guardo la ruta relativa en la base de datos que al mismo tiempo se guardan la imagen en una carpeta de mi aplicación. Me imagino que a eso te referías verdad? ahora para mostrarla en el datagrid o en un listview no se si eso sera lo mas fácil o lo mas difícil , e leído que creando un DataTemplete ojala ahí me puedas ayudar..de antemano gracias david..
    martes, 15 de mayo de 2012 23:12
  • Hola Gilberto.

    Bien, si ya tienes los datos en la BBDD y las fotos en una carpeta, solo tienes que obtener los registros de la BBDD y cargar un listview desde una plantilla como bien indicas, de modo que te pongo un ejemplillo para que te hagas una idea basica:

    Codigo xaml con el ListView y la plantilla:

    	<Window.Resources>       
            <!-- Recurso con el viewmodel -->
    		<local:ImageViewModel x:Key="ImageViewModelDataSource" d:IsDataSource="True"/>
            <!-- Conversor para cargar las imagenes desde archivos -->
            <local:PathToImageConverter x:Key="PathToImageConverter" />
            
            <!-- Plantilla del listview -->
            <DataTemplate x:Key="ListViewTemplate">
                <StackPanel Orientation="Horizontal">
                    <TextBlock TextWrapping="Wrap" Text="{Binding Id}" VerticalAlignment="Center" />
                    <Image Height="100" Width="100" Source="{Binding Converter={StaticResource PathToImageConverter}, Path=Path}" Margin="20,0"/>
                    <TextBlock TextWrapping="Wrap" Text="{Binding Description}" VerticalAlignment="Center"></TextBlock>
                </StackPanel>
            </DataTemplate>
            
        </Window.Resources>
        
        <Grid DataContext="{Binding Source={StaticResource ImageViewModelDataSource}}">
            
            <!-- ListView con las imagenes -->
            <ListView ItemTemplate="{DynamicResource ListViewTemplate}" ItemsSource="{Binding Images}" >        	
            </ListView>
        </Grid>

    En este codigo el tag '<local' es el mismo namespace de la aplicacion, tan solo creo un listview, una plantilla para el listview y creo 2 recursos, uno para establecer el contexto de datos del Viewmodel y otro para el conversor que cargara las imagenes desde los archivos.

    Codigo cs.

     /// <summary>
        /// Lógica de interacción para MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
    
        /// <summary>
        /// Modelo con los datos de la imagen
        /// </summary>
        public class ImageModel
        {
            public int Id { get; set; }
            public string Path { get; set; }
            public string Description { get; set; }
        }
    
        /// <summary>
        /// Clase con el viewModel relacionado con las imagenes
        /// </summary>
        public class ImageViewModel
        {
            public ImageViewModel()
            {
                // inicializar la coleccion de imagenes
                Images = new List<ImageModel>()
                {
                    new ImageModel(){ Id = 1, Path="Images/Img1.jpg", Description = "Foto de prueba 1" }, 
                    new ImageModel(){ Id = 1, Path="Images/Img2.jpg", Description = "Foto de prueba 2" }, 
                    new ImageModel(){ Id = 1, Path="Images/Img3.jpg", Description = "Foto de prueba 3" }, 
                };
            }
    
            /// <summary>
            /// Propiedad conteniendo una coleccion de imagenes
            /// </summary>
            public List<ImageModel> Images { get; set; }
        }
    
        /// <summary>
        /// Conversor para convertir una ruta en una fuente para imagenes
        /// </summary>
        public class PathToImageConverter : IValueConverter
        {
            /// <summary>Ruta base de la aplicacion</summary>
            private static string basePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
    
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {            
                try
                {
                    // retornar un BitmapImage cargado desde la ruta
                    Uri uri = new Uri(System.IO.Path.Combine(basePath, (string)value));
                    return new BitmapImage(uri);
                }
                catch (Exception)
                {
                    return null;
                }
            }
    
            // No hace falta implementar actualmente
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

    He puesto todo en un mismo archivo para simplificar, pero el codigo esta basado en las buenas practicas usando un modelo, un viewmodel que se usara como contexto de datos y un conversor para cargar las imagenes en el enlace de datos (nada de eventos), esto permite mucha mas flexibilidad en los enlaces con el codigo xaml.

    Bueno, el codigo no es nada del otro mundo, tan solo que yo he inicializado el viewmodel con unos datos a mano, lo que tu tendras que hacer es obtenerlos de la BBDD e inicializarlos cuando corresponda en tu aplicacion.

    Si tienes algun problema con el codigo comentalo.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    • Propuesto como respuesta CorsarioVasco jueves, 17 de mayo de 2012 8:19
    miércoles, 16 de mayo de 2012 21:56
  • Muchas gracias david, nada mas como y me pongo hacerlo....
    miércoles, 16 de mayo de 2012 22:06
  • hola estoy siguiendo tu ejemplo pero al agregar el codigo xaml m manda varios errores, ayuda por favor, o como puedo mostrar una imagen de una base de datos en un datagrid??? 

    saludos

    jueves, 18 de octubre de 2012 15:53
  • Hola Liz.

    ¿Que errrores te muestra?


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    lunes, 22 de octubre de 2012 6:30