Image UriSource y enlace de datos

Estoy intentando vincular una lista de objetos personalizados a una imagen de WPF como esta:

     

Pero no funciona. Este es el error que estoy recibiendo:

“La propiedad ‘UriSource’ o la propiedad ‘StreamSource’ deben estar configuradas”.

¿Qué me estoy perdiendo?

WPF tiene convertidores incorporados para ciertos tipos. Si enlaza la propiedad Source la imagen a una string o un valor Uri , debajo del capó WPF usará un ImageSourceConverter para convertir el valor en una ImageSource .

Asi que

  

funcionaría si la propiedad ImageSource fuera una representación de cadena de un URI válido para una imagen.

Por supuesto, puede lanzar su propio convertidor de enlace:

 public class ImageConverter : IValueConverter { public object Convert( object value, Type targetType, object parameter, CultureInfo culture) { return new BitmapImage(new Uri(value.ToString())); } public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } 

y úsalo así:

  

Este artículo de Atul Gupta tiene un código de muestra que cubre varios escenarios:

  1. Enlace de imagen de recurso regular a propiedad de origen en XAML
  2. Imagen de recurso vinculante, pero de código detrás
  3. Enlace de la imagen de recurso en el código detrás mediante el uso de Application.GetResourceStream
  4. Cargando la imagen de la ruta del archivo a través de la secuencia de la memoria (lo mismo se aplica al cargar datos de imágenes del blog desde la base de datos)
  5. Cargando la imagen desde la ruta del archivo, pero usando el enlace a una ruta de archivo Propiedad
  6. Enlace de datos de imagen a un control de usuario que internamente tiene control de imagen a través de la propiedad de dependencia
  7. Igual que el punto 5, pero también asegura que el archivo no se bloquea en el disco duro

También puede simplemente configurar el atributo Fuente en lugar de usar los elementos secundarios. Para hacer esto, su clase necesita devolver la imagen como una Imagen de Mapa de bits. Aquí hay un ejemplo de una forma en que lo hice

  

Y la propiedad de la clase es simplemente esto

 public object ImageSource { get { BitmapImage image = new BitmapImage(); try { image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.CreateOptions = BitmapCreateOptions.IgnoreImageCache; image.UriSource = new Uri( FullPath, UriKind.Absolute ); image.EndInit(); } catch{ return DependencyProperty.UnsetValue; } return image; } } 

Supongo que puede ser un poco más de trabajo que el convertidor de valor, pero es otra opción.

Debe tener una implementación de la interfaz IValueConverter que convierta el uri en una imagen. La implementación Convert de IValueConverter tendrá un aspecto similar a este:

 BitmapImage image = new BitmapImage(); image.BeginInit(); image.UriSource = new Uri(value as string); image.EndInit(); return image; 

Entonces necesitarás usar el convertidor en tu enlace:

      

El problema con la respuesta que se eligió aquí es que, al navegar de ida y vuelta, el convertidor se activará cada vez que se muestre la página.

Esto provoca que se creen continuamente nuevos identificadores de archivo y bloqueará cualquier bash de eliminar el archivo porque todavía está en uso. Esto se puede verificar usando Process Explorer.

Si el archivo de imagen se puede eliminar en algún momento, se puede usar un convertidor como este: usar XAML para enlazar a System.Drawing.Image en un control System.Windows.Image

La desventaja de este método de flujo de memoria es que las imágenes se cargan y decodifican cada vez y no se puede almacenar en caché: “Para evitar que las imágenes se decodifiquen más de una vez, asigne la propiedad Image.Source de un Uri en lugar de usar secuencias de memoria “Fuente:” Sugerencias de rendimiento para aplicaciones de Windows Store utilizando XAML ”

Para resolver el problema de rendimiento, el patrón de repository se puede utilizar para proporcionar una capa de almacenamiento en caché. El almacenamiento en caché puede tener lugar en la memoria, lo que puede causar problemas de memoria, o como archivos en miniatura que residen en una carpeta temporal que se puede borrar cuando la aplicación se cierra.

puedes utilizar

Clase ImageSourceConverter

para obtener lo que quieres

  img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");