Wpf 将DataTemplate中的图像绑定到System.Drawing.Image

Wpf 将DataTemplate中的图像绑定到System.Drawing.Image,wpf,image,binding,Wpf,Image,Binding,我正在尝试将DataTemplate中的Image.Source绑定到System.Drawing.Image,如下所述: GameTile对象具有指向图片对象的Image(而不是system.drawing.Image)属性,该图片对象具有system.drawing.Image类型的Image属性。 我正在将列表框上的ItemsSource绑定到游戏对象上的GameTiles集合 对象 public class Game { public XPCollection<Game

我正在尝试将DataTemplate中的Image.Source绑定到System.Drawing.Image,如下所述:


GameTile对象具有指向图片对象的Image(而不是system.drawing.Image)属性,该图片对象具有system.drawing.Image类型的Image属性。 我正在将列表框上的ItemsSource绑定到游戏对象上的GameTiles集合

对象

public class Game
{
    public XPCollection<GameTile> GameTiles
    {
        get { return GetCollection<GameTile>("GameTiles"); }
    }
}

public class GameTiles
{
    Picture fImage;
    public Picture Image
    {
        get { return fImage; }
        set { SetPropertyValue<Picture>("Image", ref fImage, value); }
    }
}

public class Picture
{

    private FileData fFile;
    public FileData File
    {
        get { return fFile; }
        set
        {
            SetPropertyValue("File", ref fFile, value);
            if (string.IsNullOrEmpty(fName))
            {
                fName = (value == null ? string.Empty : value.FileName);
            }
            fImage = null;
        }
    }

    Image fImage;
    public System.Drawing.Image Image
    {
        get 
        {
            if (fImage == null)
            {
                try
                {
                    MemoryStream stream = new MemoryStream();
                    fFile.SaveToStream(stream);
                    stream.Position = 0;
                    fImage = Image.FromStream(stream);
                }
                catch 
                { 
                    //TODO: log exception
                }
            }
            return fImage;
        }
        //set { SetPropertyValue<Image>("Image", ref fImage, value); }
    }
}
公共类游戏
{
公共游戏片
{
获取{return GetCollection(“GameTiles”);}
}
}
公共类游戏片
{
图片图像;
公共图片形象
{
获取{return fImage;}
set{SetPropertyValue(“Image”,ref fImage,value);}
}
}
公开课图片
{
私有文件数据文件;
公共文件数据文件
{
获取{return fFile;}
设置
{
SetPropertyValue(“文件”,参考文件,值);
if(string.IsNullOrEmpty(fName))
{
fName=(value==null?string.Empty:value.FileName);
}
fImage=null;
}
}
图像;
公共系统.绘图.图像
{
得到
{
if(fImage==null)
{
尝试
{
MemoryStream stream=新的MemoryStream();
fFile.SaveToStream(stream);
流位置=0;
fImage=Image.FromStream(流);
}
抓住
{ 
//TODO:日志异常
}
}
返回图像;
}
//set{SetPropertyValue(“Image”,ref fImage,value);}
}
}
图像不会显示在ListBoxItems中,但我在DataTemplate中绑定的任何其他属性都会显示出来。值得注意的是,我使用Devexpress Xpo作为ORM。上面表示的类也实现了INotifyPropertyChanged。 有没有想过我可能会错过什么

编辑:忘记提到我已经实现了一个值转换器,正如我在上面链接的帖子中提到的。但是,如果我在converter方法中放置断点,则永远不会调用它

编辑:将fFile属性添加到上面的代码中。 我可以通过c#将Image.Source设置为GameTile.Image.Image属性(通过将其转换为BitmapImage),并使其按预期工作,但我不确定如何通过c#使用DataTemplate实现这一点。我更愿意用XAML设置绑定,但我愿意用数据模板(或者其他可以工作的东西)解决c#问题。我很有信心,问题不在于GameTile.Image属性从数据库中提取图像,因为如果我在c#中手动设置Image.source的源,图像就在那里。它在DataTemplate中根本不起作用

编辑:确定问题与我绑定到的数据类型不直接相关的属性有关,例如,GameTile具有(int)PointValue属性、(图片对象)图像属性和(奖品对象)奖品属性

<Image Margin="0,5,0,0" Source="{Binding Path=Image!.Image, Converter={StaticResource imageConverter}}" />
如果我必须

<TextBlock Text="{Binding PointValue}" /> 
<TextBlock Text="{Binding Prize.Name}" /> 
<Image Margin="0,5,0,0" Source="{Binding Image.BitmapImage}" />

它按预期工作。 但如果我一定要

<TextBlock Text="{Binding PointValue}" /> 
<TextBlock Text="{Binding Prize.Name}" /> 
<Image Margin="0,5,0,0" Source="{Binding Image.BitmapImage}" />

它不起作用。 如果我一定要

<TextBlock Text="{Binding PointValue}" /> 
<TextBlock Text="{Binding Prize.Name}" /> 
<Image Margin="0,5,0,0" Source="{Binding Image.BitmapImage}" />

它也失败了。下图显示了绑定引发的错误

BindingExpression路径错误:“对象”上未找到“名称”属性 “XPCollection”(哈希=…)”。BindingExpression:Path=Prize.Name; DataItem=GameTile'(HashCode=…);目标元素是 “TextBlock”(名称=“”);目标属性为“Text”(类型为“String”)

谢谢, 埃里克找到了解决办法。 必须改变这一点:

<TextBlock Text="{Binding Prize.Name}" /> 

为此:

<TextBlock Text="{Binding Prize!.Name}" /> 

唯一的区别是感叹号(!)。 这也适用于图像属性

<Image Margin="0,5,0,0" Source="{Binding Path=Image!.Image, Converter={StaticResource imageConverter}}" />

找到了解决方案。 必须改变这一点:

<TextBlock Text="{Binding Prize.Name}" /> 

为此:

<TextBlock Text="{Binding Prize!.Name}" /> 

唯一的区别是感叹号(!)。 这也适用于图像属性

<Image Margin="0,5,0,0" Source="{Binding Path=Image!.Image, Converter={StaticResource imageConverter}}" />


也许可以向catch块添加一些代码
//TODO:log exception
。如果从流加载图像,为什么不直接按其属性加载BitmapImage?您可以将
图像
属性的类型更改为,并且不需要任何转换器。您在转换器中到底在做什么?如果“Image.Image”返回“Stream”(字节数组),则不需要任何转换器,可以直接将其绑定到ImageSource。如果您使用的是converter,则该转换器应返回一个“BitmapImage”。能否显示fFile属性/字段以及操作该属性/字段的代码?@Clemens:catch块不是问题所在。我在这里设置了一个永远不会被击中的断点。并且image属性有一个值,我只是不确定是否正确绑定了它。也许您可以向catch块添加一些代码
//TODO:log exception
。如果从流加载图像,为什么不直接按其属性加载BitmapImage?您可以将
图像
属性的类型更改为,并且不需要任何转换器。您在转换器中到底在做什么?如果“Image.Image”返回“Stream”(字节数组),则不需要任何转换器,可以直接将其绑定到ImageSource。如果您使用的是converter,则该转换器应返回一个“BitmapImage”。能否显示fFile属性/字段以及操作该属性/字段的代码?@Clemens:catch块不是问题所在。我在这里设置了一个永远不会被击中的断点。而image属性有一个值,我只是不确定是否正确绑定了它。