Pregunta

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

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding Path=ImagePath}" />
    </Image.Source>
</Image>

Pero no funciona.Este es el error que recibo:

"Se debe configurar la propiedad 'UriSource' o la propiedad 'StreamSource'".

¿Qué me estoy perdiendo?

¿Fue útil?

Solución

WPF tiene convertidores integrados para ciertos tipos.Si unes la imagen Source propiedad a un string o Uri valor, bajo el capó WPF utilizará un ImageSourceConverter para convertir el valor a un ImageSource.

Entonces

<Image Source="{Binding ImageSource}"/>

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

Por supuesto, puedes ejecutar tu propio convertidor de enlaces:

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 usarlo así:

<Image Source="{Binding ImageSource, Converter={StaticResource ImageConverter}}"/>

Otros consejos

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

  1. Enlace de imagen de recurso regular a la propiedad Fuente en XAML
  2. Imagen de recurso vinculante, pero desde el código subyacente.
  3. Vincular imagen de recurso en el código subyacente mediante Application.GetResourceStream
  4. Carga de imágenes desde la ruta del archivo a través del flujo de memoria (lo mismo se aplica al cargar datos de imágenes de blog desde la base de datos)
  5. Cargando imagen desde la ruta del archivo, pero usando el enlace a una propiedad de ruta del archivo
  6. Vincular 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 asegurando que el archivo no quede bloqueado en el disco duro.

También puede simplemente establecer el atributo Fuente en lugar de utilizar 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 he hecho.

<Image Width="90" Height="90" 
       Source="{Binding Path=ImageSource}"
       Margin="0,0,0,5" />

Y la propiedad de clase es simplemente esta

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 trabajo que el conversor de valores, pero es otra opción.

Necesitas tener una implementación de IValueConvertidor Interfaz que convierte el uri en una imagen.Su implementación Convert de IValueConverter se verá así:

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

return image;

Luego necesitarás usar el convertidor en tu enlace:

<Image>
    <Image.Source>
        <BitmapImage UriSource="{Binding Path=ImagePath, Converter=...}" />
    </Image.Source>
</Image>

El problema con la respuesta que se eligió aquí es que al navegar hacia adelante y hacia atrás, el convertidor se activará cada vez que se muestre la página.

Esto hace que se creen continuamente nuevos identificadores de archivos y bloqueará cualquier intento de eliminar el archivo porque todavía está en uso.Esto se puede verificar utilizando Process Explorer.

Si el archivo de imagen pudiera eliminarse en algún momento, se podría utilizar un convertidor como este:usar XAML para vincular un System.Drawing.Image a 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 realizar ningún almacenamiento en caché:"Para evitar que las imágenes se decodifiquen más de una vez, asigne la propiedad de la imagen."Consejos de rendimiento para aplicaciones de la Tienda Windows que utilizan XAML"

Para resolver el problema de rendimiento, se puede utilizar el patrón de repositorio para proporcionar una capa de almacenamiento en caché.El almacenamiento en caché podría realizarse 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 se cierra la aplicación.

puedes utilizar

Clase ImageSourceConverter

para conseguir lo que quieres

    img1.Source = (ImageSource)new ImageSourceConverter().ConvertFromString("/Assets/check.png");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top