C#WPF-将图像从字节数组加载到Datagrid [英] C# WPF - Load Image from bytearray into Datagrid
问题描述
我有一个WPF表单(我完全是WPF的初学者),其中包含一个Datagrid
.此Datagrid
通过简单的List<AudioFile>
获取其内容.在扩展AudioFile
的类Mp3File
中(在PCL内部)是一个名为GetCoverAsByteArray()
的方法,该方法将已加载的AudioFile
的封面返回为byte[]
.
现在,我想在DataGrid
中显示封面图像,但是我不知道该怎么做.你能帮我吗?
I've got a WPF Form (I am totally a beginner in WPF) which contains a Datagrid
. This Datagrid
gets its Content by a simple List<AudioFile>
. Inside the class Mp3File
which extends AudioFile
(It's inside a PCL) is a method called GetCoverAsByteArray()
, which returns the cover of a loaded AudioFile
as a byte[]
.
Now i want to show the cover Image in the DataGrid
, but i don't know how to do it. Can you please help me?
这是我到目前为止的代码:
Here is the code i have so far:
<DataGrid x:Name="tvFiles" AutoGenerateColumns="False" MaxColumnWidth="1000" Margin="10,95,10,10" MinHeight="100">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Cover" Width="*" MinWidth="64">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Filename" Width="*" MinWidth="100" Binding="{Binding Filename}"/>
<DataGridTextColumn Header="Artist" Width="*" MinWidth="50" Binding="{Binding Artist}"/>
<DataGridTextColumn Header="Title" Width="*" MinWidth="50" Binding="{Binding Title}"/>
<DataGridTextColumn Header="Album" Width="*" MinWidth="50" Binding="{Binding Album}"/>
<DataGridTextColumn Header="BPM" Width="*" MinWidth="50" Binding="{Binding BPM}"/>
<DataGridTextColumn Header="Comment" Width="*" MinWidth="100" Binding="{Binding Comment}"/>
<DataGridTextColumn Header="Year" Width="*" MinWidth="40" Binding="{Binding Year}"/>
<DataGridTextColumn Header="Key" Width="*" MinWidth="40" Binding="{Binding Key}"/>
<DataGridTextColumn Header="Bitrate" Width="*" MinWidth="60" Binding="{Binding Bitrate}"/>
<DataGridTextColumn Header="Length" Width="*" MinWidth="50" Binding="{Binding Duration}"/>
</DataGrid.Columns>
</DataGrid>
非常感谢您的帮助
编辑1
我实现了丹尼斯所说的Converted,现在我的代码如下:
I implemented a Converted like Dennis has said and now my code looks like this:
class ByteArrayToImageConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
byte[] bytes = (byte[])value;
if (bytes == null || bytes.Length == 0) return null;
var image = new BitmapImage();
using (var mem = new MemoryStream(bytes)) {
mem.Position = 0;
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
<Window.Resources>
<local:ByteArrayToImageConverter x:Key="converter" />
</Window.Resources>
<DataGrid x:Name="tvFiles" AutoGenerateColumns="False" MaxColumnWidth="1000" Margin="10,95,10,10" MinHeight="100">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Cover" Width="*" MinWidth="64">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding GetCoverAsByteArray, Converter={StaticResource converter}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Filename" Width="*" MinWidth="100" Binding="{Binding Filename}"/>
<DataGridTextColumn Header="Artist" Width="*" MinWidth="50" Binding="{Binding Artist}"/>
<DataGridTextColumn Header="Title" Width="*" MinWidth="50" Binding="{Binding Title}"/>
<DataGridTextColumn Header="Album" Width="*" MinWidth="50" Binding="{Binding Album}"/>
<DataGridTextColumn Header="BPM" Width="*" MinWidth="50" Binding="{Binding BPM}"/>
<DataGridTextColumn Header="Comment" Width="*" MinWidth="100" Binding="{Binding Comment}"/>
<DataGridTextColumn Header="Year" Width="*" MinWidth="40" Binding="{Binding Year}"/>
<DataGridTextColumn Header="Key" Width="*" MinWidth="40" Binding="{Binding Key}"/>
<DataGridTextColumn Header="Bitrate" Width="*" MinWidth="60" Binding="{Binding Bitrate}"/>
<DataGridTextColumn Header="Length" Width="*" MinWidth="50" Binding="{Binding Duration}"/>
</DataGrid.Columns>
</DataGrid>
现在,当将AudioFile加载到Datagrid时,我会收到以下消息:
Now i get the following Message when loading a AudioFile into the Datagrid:
System.Windows.Data错误:40:BindingExpression路径错误:在对象""Mp3File"(HashCode = 54312533)上找不到"GetCoverAsByteArray()"属性. BindingExpression:Path = GetCoverAsByteArray(); DataItem ='Mp3File'(HashCode = 54312533);目标元素是'Image'(Name ='');目标属性为来源"(类型为图片来源")
System.Windows.Data Error: 40 : BindingExpression path error: 'GetCoverAsByteArray()' property not found on 'object' ''Mp3File' (HashCode=54312533)'. BindingExpression:Path=GetCoverAsByteArray(); DataItem='Mp3File' (HashCode=54312533); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource')
System.Windows.Data错误:40:BindingExpression路径错误:在对象""Mp3File"(HashCode = 54312533)上找不到"Key"属性. BindingExpression:Path = Key; DataItem ='Mp3File'(HashCode = 54312533);目标元素是'TextBlock'(Name ='');目标属性是文本"(类型为字符串")
System.Windows.Data Error: 40 : BindingExpression path error: 'Key' property not found on 'object' ''Mp3File' (HashCode=54312533)'. BindingExpression:Path=Key; DataItem='Mp3File' (HashCode=54312533); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
推荐答案
数据绑定仅适用于属性.您必须向AudioFile
类添加属性以返回封面数据.如果由于某些原因不想更改AudioFile
,则将其映射/包装到视图模型中,然后将属性放入该视图模型中.
Data binding works for properties only. You have to add a property to AudioFile
class to return cover data. If you don't want to change AudioFile
for some reasons, then map it/wrap it into view model, and place property into that view model.
然后您将有两个选择.
您可以代替public byte[] CoverAsByteArray { get; }
编写属性,该属性返回
Instead of public byte[] CoverAsByteArray { get; }
you can write a property, which returns ImageSource
instance, something like public ImageSource CoverAsImageSource { get; }
.
XAML将如下所示:
XAML will look like this:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding CoverAsImageSource}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
选项2.
您可以写一个在这种情况下,XAML将如下所示:
In this case, XAML will look like this:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding CoverAsByteArray, Converter={StaticResource YourConverterKey}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
假设byte[]
代表位图,则可以使用此答案将其转换为适当的位图图片来源.
Assuming, that byte[]
represents a bitmap, you can use, e.g., this answer to convert it to appropriate image source.
这篇关于C#WPF-将图像从字节数组加载到Datagrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!