我试图为我的列表视图构建一个项目模板,并且我绑定到一个实体列表。我所拥有的实体有System.Drawing.Image
我想展示,但到目前为止,我不能为我的生活弄清楚如何将它绑定到<Image>
块。
我可以在互联网上找到的每个示例和文档都适用于可通过uri
访问的图像,即HDD或网站上的文件
<DataTemplate x:Key="LogoPreviewItem">
<Border BorderBrush="Black" BorderThickness="1">
<DockPanel Width="150" Height="100">
<Image>
<Image.Source>
<!--
{Binding PreviewImage} is where the System.Drawing.Image
is in this context
-->
</Image.Source>
</Image>
<Label DockPanel.Dock="Bottom" Content="{Binding CustomerName}" />
</DockPanel>
</Border>
</DataTemplate>
答案 0 :(得分:4)
System.Drawing.Image是一个WinForms / GDI +对象,在WPF世界中确实不合适。纯WPF程序通常不会使用System.Drawing.Image,而是使用BitmapSource。然而,有时我们会坚持旧的东西。
您可以将图像从旧技术转换为新技术,如下所示:
var oldImage = ...; // System.Drawing.Image
var oldBitmap =
oldImage as System.Drawing.Bitmap ??
new System.Drawing.Bitmap(oldImage);
var bitmapSource =
System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
oldBitmap.GetHbitmap(System.Drawing.Color.Transparent),
IntPtr.Zero,
new Int32Rect(0, 0, oldBitmap.Width, oldBitmap.Height),
null);
现在你可以设置:
myImage.Source = bitmapSource;
这比您在其他地方描述的MemoryStream方法快得多,因为它从未将位图数据序列化为流。
答案 1 :(得分:0)
Ray Burns的答案自此以来导致内存泄漏
oldBitmap.GetHbitmap(System.Drawing.Color.Transparent)
分配永远不会释放的内存。
如GetHbitmap
(Microsoft Docs)文档中“备注”所述:
您负责调用GDI DeleteObject方法以释放GDI位图对象使用的内存。
按照说明文件,通过导入和使用DeleteObject()
释放内存:
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
var hBitmap = someBitmap.GetHbitmap(...);
// Do something with hBitmap
DeleteObject(hBitmap);
因此,Ray Burns的答案应修改为:
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
...
var oldImage = ...; // System.Drawing.Image
var oldBitmap =
oldImage as System.Drawing.Bitmap ??
new System.Drawing.Bitmap(oldImage);
var hOldBitmap = oldBitmap.GetHbitmap(System.Drawing.Color.Transparent);
var bitmapSource =
System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hOldBitmap,
IntPtr.Zero,
new Int32Rect(0, 0, oldBitmap.Width, oldBitmap.Height),
null);
DeleteObject(hOldBitmap);