2010-08-06 24 views
12

Estoy vinculando un ListView a una lista de objetos, como tal;usando XAML para enlazar a System.Drawing.Image en un control System.Windows.Image

<ListView 
    ItemsSource="{ Binding Path=. }" 
    ItemTemplate="{DynamicResource EventTemplate}"> 

Estoy vinculando a un objeto que declara dos propiedades;

string DisplayName { get; } 
System.Drawing.Image Image { get; set; } 

Quiero llenar un DataTemplate pero no puedo encontrar la manera; si hago esto en mi plantilla;

<StackPanel Orientation="Horizontal"> 
    <Image Source="{ Binding Path=Image }" /> 
    <TextBlock Text="{ Binding Path=DisplayName }" /> 
</StackPanel>  

Aparece el texto pero la imagen no. ¿Qué estoy haciendo mal? El resultado de la depuración muestra

System.Windows.Data Error: 1 : Cannot create default converter 
to perform 'one-way' conversions between types 
'System.Drawing.Image' and 'System.Windows.Media.ImageSource'. 
Consider using Converter property of Binding. 
BindingExpression:Path=Image; DataItem='RealElement' 
(HashCode=54308798); target element is 'Image' (Name=''); 
target property is 'Source' (type 'ImageSource') 

Respuesta

34

Encontré una manera con la que estoy contento. Utilizando Reed Copsey's pointer y this tutorial he envuelto el código como IValueConverter.

Aquí está el convertidor de System.Drawing.Image a System.Windows.Media.ImageSource;

using System; 
using System.Drawing.Imaging; 
using System.Globalization; 
using System.IO; 
using System.Windows.Data; 

namespace System.Windows.Media 
{ 
    /// <summary> 
    /// One-way converter from System.Drawing.Image to System.Windows.Media.ImageSource 
    /// </summary> 
    [ValueConversion(typeof(System.Drawing.Image), typeof(System.Windows.Media.ImageSource))] 
    public class ImageConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, 
      object parameter, CultureInfo culture) 
     { 
      // empty images are empty... 
      if (value == null) { return null; } 

      var image = (System.Drawing.Image)value; 
      // Winforms Image we want to get the WPF Image from... 
      var bitmap = new System.Windows.Media.Imaging.BitmapImage(); 
      bitmap.BeginInit(); 
      MemoryStream memoryStream = new MemoryStream(); 
      // Save to a memory stream... 
      image.Save(memoryStream, ImageFormat.Bmp); 
      // Rewind the stream... 
      memoryStream.Seek(0, System.IO.SeekOrigin.Begin); 
      bitmap.StreamSource = memoryStream; 
      bitmap.EndInit(); 
      return bitmap; 
     } 

     public object ConvertBack(object value, Type targetType, 
      object parameter, CultureInfo culture) 
     { 
      return null; 
     } 
    } 
} 

Luego debe llevar el convertidor de imágenes a XAML como recurso;

xmlns:med="clr-namespace:System.Windows.Media" 
... 

<ListView.Resources> 
    <med:ImageConverter x:Key="imageConverter" /> 
</ListView.Resources> 

Luego puede usarlo en XAML para enlazar directamente a la imagen, utilizando el nuevo convertidor;

<Image Source="{ Binding Path=Image, Converter={StaticResource imageConverter} }" /> 
+1

Tengo una pregunta sobre el uso de la memoria: ¿esta conversión tiene lugar solo una vez o cada vez que se muestra la imagen en la parte visible de, por ejemplo, ListBox? – emesx

+1

Realmente no puedo decir: la conversión se realiza cada vez que WPF lo necesita, así que creo que es solo un detalle interno de la implementación. No creo que haya ninguna razón para que se convierta una y otra vez, pero podría valer la pena meterse en un mostrador y ver ... –

+1

'memoryStream' nunca se cierra o se desecha, ¿eso es una preocupación aquí? Tengo un código muy similar, que incluso podría haber surgido de esta pregunta, pero es más feo. – Maslow

4

No se puede obligar a que directamente - es necesario tener algún tipo de convertidor que convertirá a partir de un GDI imagen a una imagen de WPF.

Aquí está one approach - utiliza una secuencia de memoria para extraer los datos de la imagen GDI y crear un objeto BitmapSource.

+0

Hola, gracias por el puntero. Estoy leyendo sus artículos sobre "Mejores experiencias de usuario y desarrollador: de Windows Forms a WPF con MVVM" en este momento; Buena cosa. De todos modos, eso me dio suficiente para llegar a la respuesta; Lo he publicado al lado. –

+0

@Steve: Me alegra saber que te gusta la serie;) –

+0

Ha sido muy útil. El modelo de WPF es muy diferente de las formas de Windows, y tus ensayos me ayudan a desbloquearlo en mi cerebro. –

Cuestiones relacionadas