La solución consiste en anular la vista del elemento DataTemplate.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
xmlns:self="clr-namespace:WpfApplication1"
xmlns:props="clr-namespace:WpfApplication1.Properties">
<Window.Resources>
<self:ImageConverter x:Key="Conv"/>
<DataTemplate x:Key="Template">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=Icon, Converter={StaticResource Conv}}"
Width="64"
Height="64"/>
<TextBlock Text="{Binding Name}"
VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ListView ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource Template}"/>
</StackPanel>
Entonces tenemos que fijar nuestra PresentationModel como DataContext de vista en el código detrás de este punto de vista:
public MainWindow()
{
InitializeComponent();
this.DataContext = new SampleModel();
}
Como se puede ver en expresión de enlace en XAML nuestro modelo de presentación debe exponer propiedad Items (si considera cambiar la lista de elementos en tiempo de ejecución, la colección subyacente debe ser ObservableCollection para que ListView reaccione ante sus cambios):
public class SampleModel
{
public IEnumerable<ViewData> Items
{
get
{
yield return new ViewData(Properties.Resources.airbrush_256, "item 1");
yield return new ViewData(Properties.Resources.colors_256, "item 2");
yield return new ViewData(Properties.Resources.distribute_left_edge_256, "item 3");
yield return new ViewData(Properties.Resources.dossier_ardoise_images, "item 4");
}
}
}
public class ViewData
{
public ViewData(Bitmap icon, string name)
{
this._icon = icon;
this._name = name;
}
private readonly Bitmap _icon;
public Bitmap Icon
{
get
{
return this._icon;
}
}
private readonly string _name;
public string Name
{
get
{
return this._name;
}
}
}
En esta solución agrego imágenes PNG existentes a Properties.Resources class. A continuación, los iconos de mapa de bits tiene el tipo que no es compatible con el tipo de propiedad Source, por lo que debemos convertirlo a BitmapSource con el siguiente conversor:
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Bitmap)
{
var stream = new MemoryStream();
((Bitmap)value).Save(stream, ImageFormat.Png);
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = stream;
bitmap.EndInit();
return bitmap;
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Por otro lado se puede utilizar para almacenar pack uri's iconos en lugar de recursos. Entonces su clase ViewData expondrá la propiedad de tipo Uri (en lugar de Bitmap). Entonces no se necesitan convertidores.
enlace roto, yo usaría un servicio que no sea imgur, ya que 9/10 enlaces imgur que veo en Internet están rotos. – msbg