我有一个WPF表格(我完全是WPF的初学者),其中包含Datagrid
。此Datagrid
通过简单的List<AudioFile>
获取其内容。扩展Mp3File
(它在PCL中)的类AudioFile
内部是一个名为GetCoverAsByteArray()
的方法,它将加载的AudioFile
的封面作为byte[]
返回。
现在我想在DataGrid
中显示封面图片,但我不知道该怎么做。你能帮我吗?
这是我到目前为止的代码:
<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
我实现了像Dennis所说的Converted,现在我的代码看起来像这样:
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时,我收到以下消息:
System.Windows.Data错误:40:BindingExpression路径错误:'对象'''Mp3File'(HashCode = 54312533)'上找不到'GetCoverAsByteArray()'属性。 BindingExpression:路径= GetCoverAsByteArray(); DataItem ='Mp3File'(HashCode = 54312533); target元素是'Image'(Name =''); target属性是'Source'(类型'ImageSource')
System.Windows.Data错误:40:BindingExpression路径错误:'对象'''Mp3File'(HashCode = 54312533)'上找不到'Key'属性。 BindingExpression:路径=关键; DataItem ='Mp3File'(HashCode = 54312533); target元素是'TextBlock'(Name =''); target属性是'Text'(类型'String')
答案 0 :(得分:1)
您可以使用Microsoft.WindowsAPICodePack.Shell从您的mp3文件中获取图像
private string cacheLocalFile(string mp3fileName)
{
try
{
using (var shell = ShellFile.FromParsingName(mp3fileName))
{
Bitmap bmp = shell.Thumbnail.Bitmap;
var cachedFileName = shell.Properties.System.FileName.Value;
bmp.Save(Path.Combine(AppCacheDirectory, cachedFileName), ImageFormat.Jpeg);
bmp.Dispose();
return Path.Combine(AppCacheDirectory, cachedFileName);
}
}
catch
{
return String.Empty;
}
}
你刚刚获得了缩略图,将其保存到文件中并将文件src返回给Image元素,如果你不想缓存图像,你可以将位图转换为bitmapImage并将其绑定到视图中的图像元素。
答案 1 :(得分:0)
数据绑定仅适用于属性。您必须向AudioFile
类添加属性才能返回封面数据。如果由于某些原因不想更改AudioFile
,请将其映射/包装到视图模型中,并将属性放入该视图模型中。
然后你将有两个选择。
您可以编写一个返回ImageSource
实例的属性,而不是public byte[] CoverAsByteArray { get; }
,而不是public ImageSource CoverAsImageSource { get; }
。
XAML将如下所示:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding CoverAsImageSource}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
您可以写一个值converter,将byte[]
值转换为ImageSource
。
在这种情况下,XAML将如下所示:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding CoverAsByteArray, Converter={StaticResource YourConverterKey}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
假设byte[]
表示位图,您可以使用例如this answer将其转换为适当的图像源。