C#WPF-将图像从字节数组加载到Datagrid [英] C# WPF - Load Image from bytearray into Datagrid

查看:114
本文介绍了C#WPF-将图像从字节数组加载到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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆