I have been tasked with taking an existing list of transparent .png images (currently housed within an ImageList) and displaying them in a WPF DataGrid based on the ImageID column.
I have set up the DataGridColumn as follows:
_dataTemplateColumn = new DataGridTemplateColumn();
_dataTemplateColumn.Header = "";
FrameworkElementFactory _factory = new FrameworkElementFactory(typeof(Image));
Binding _binding = new Binding("Image");
_binding.Mode = BindingMode.TwoWay;
_factory.SetValue(Image.SourceProperty, _binding);
DataTemplate _cellTemplate = new DataTemplate();
_cellTemplate.VisualTree = _factory;
_dataTemplateColumn.CellTemplate = _cellTemplate;
Style _style = new Style();
_style.Setters.Add(new Setter(BackgroundProperty, Brushes.Transparent));
_dataTemplateColumn.CellStyle = _style;
I then create a Custom Object at runtime which includes the image for me and run the following 2 methods on the Image, the first to resize it and the second to convert it into a Bitmap rather than a BitmapImage (which is the only format I have managed to get it working in WPF with so far):
public static Bitmap ResizeImage(this Bitmap Bitmap, Size size)
{
try
{
Bitmap _bitmap = new Bitmap(size.Width, size.Height);
using (Graphics _graphic = Graphics.FromImage((Image)_bitmap))
{
_graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
_graphic.DrawImage(Bitmap, 0, 0, size.Width, size.Height);
}
_bitmap.MakeTransparent(Color.Magenta);
return _bitmap;
}
catch (Exception ex)
{
throw ex;
}
}
public static Bitmap ToBitmap(this BitmapImage BitmapImage)
{
using (MemoryStream _stream = new MemoryStream())
{
BitmapEncoder _encoder = new BmpBitmapEncoder();
_encoder.Frames.Add(BitmapFrame.Create(BitmapImage));
_encoder.Save(_stream);
System.Drawing.Bitmap _bitmap = new System.Drawing.Bitmap(_stream);
_bitmap.MakeTransparent(Color.Magenta);
return new Bitmap(_bitmap);
}
}
The Image is being displayed in the correct size and position in the DataGrid but the transparency is not preserved from the .png format. If anyone knows a better method for me (perhaps it is more correct to take the Image into a resource file first for example?) or a way to get the transparency working within my current code it would be most appreciated!
The following example gives you an idea of how it may look like:
XAML:
<Window ...>
<Window.Resources>
<DataTemplate x:Key="ImageCellTemplate">
<Image Source="{Binding Image}" Width="100"/>
</DataTemplate>
</Window.Resources>
<Grid>
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False"/>
</Grid>
</Window>
Code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var col = new DataGridTemplateColumn();
col.CellTemplate = (DataTemplate)Resources["ImageCellTemplate"];
dataGrid.Columns.Add(col);
foreach (var file in Directory.EnumerateFiles(@"C:\Users\Public\Pictures\Sample Pictures", "*.jpg"))
{
dataGrid.Items.Add(new DataItem { Image = file });
}
}
}
public class DataItem
{
public string Image { get; set; }
}