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

Posted

技术标签:

【中文标题】将 DataTemplate 中的图像绑定到 System.Drawing.Image【英文标题】:Bind Image in DataTemplate to System.Drawing.Image 【发布时间】:2012-10-09 20:02:38 【问题描述】:

我正在尝试将 DataTemplate 中的 Image.Source 绑定到 System.Drawing.Image,如下所述:using XAML to bind to a System.Drawing.Image into a System.Windows.Image control

<UserControl.Resources>
    <media:ImageConverter x:Key="imageConverter" />
    <DataTemplate DataType="x:Type data:GameTile" >
        <StackPanel Orientation="Vertical" Margin="5" Background="Transparent">
            <Viewbox>
                <TextBlock FontWeight="Bold" Text="Binding PointValue" TextAlignment="Center" FontSize="14" />
            </Viewbox>
            <Image Margin="0,5,0,0" Source="Binding Path=Image.Image, Converter=StaticResource imageConverter" />
        </StackPanel>
    </DataTemplate>
</UserControl.Resources>
    <Grid>
        <loop:ListBox x:Name="listBox1" 
                         ItemsSource="Binding Path=GameModel.Game.GameTiles"
                         ItemContainerStyle="StaticResource GameTileContainerStyle" Orientation="Vertical" />
    </Grid>

GameTile 对象具有指向具有 System.Drawing.Image 类型的 Image 属性的 Picture 对象的 Image(不是 system.drawing.image)属性。 我将 ListBox 上的 ItemsSource 绑定到 Game 对象上的 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); 
    

图像未显示在 ListBoxItems 中,但我在 DataTemplate 中绑定的任何其他属性都会显示。值得注意的是,我使用 Devexpress Xpo 作为 ORM。上面表示的类也实现了 INotifyPropertyChanged。 对我可能缺少的东西有什么想法吗?

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

编辑:在上面的代码中添加了 fFile 属性。 我可以通过 c#(通过将其转换为 BitmapImage)将 Image.Source 设置为 GameTile.Image.Image 属性,并使其按预期工作,但我不确定如何通过 c# 使用 DataTemplate 来完成此操作。我更愿意在 XAML 中设置绑定,但会满足于使用 DataTemplate(或其他可行的方法)的 c# 解决方法。我非常确信问题不在于从数据库中提取图像的 GameTile.Image 属性,因为如果我在 c# 中手动设置 Image.Source 上的源,图像就在那里。它根本无法在 DataTemplate 中工作。

编辑:确定与不直接在我绑定到的 DataType 上的属性相关的问题,例如,GameTile 具有 (int)PointValue 属性、(Picture object)Image 属性和 (Prize object)奖品。

如果我绑定到

<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=...);目标元素是 '文本块'(名称='');目标属性是“文本”(类型“字符串”)

谢谢, 埃里克

【问题讨论】:

也许你在catch块//TODO: log exception中添加了一些代码。 如果从流中加载图片,为什么不直接通过StreamSource属性加载BitmapImage呢?您可以将Image 属性的类型更改为ImageSource,并且不需要任何转换器。 您在转换器中到底在做什么?如果您的“Image.Image”返回一个“Stream”(字节数组),那么您不需要任何转换器,您可以直接将其绑定到 ImageSource。如果您使用转换器,该转换器应返回“BitmapImage”。 你能显示 fFile-Property/Field 和你操作它的代码吗? @Clemens:catch 块不是问题。我在这里设置了一个永远不会被击中的断点。并且图像属性有一个值,我只是不确定我是否正确绑定它。 【参考方案1】:

找到了解决办法。 不得不改变这个:

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

到这里:

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

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

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

【讨论】:

以上是关于将 DataTemplate 中的图像绑定到 System.Drawing.Image的主要内容,如果未能解决你的问题,请参考以下文章

绑定到 DataTemplate 中的视图模型属性

将 WPF 按钮 CommandParameter 绑定到 DataTemplate 中的按钮本身

将 DataTemplate 中的按钮绑定到表单的 ViewModel 中的命令

WPF DataTemplate 绑定取决于属性的类型

如何将 DataTemplate 数据类型绑定到接口?

UWP 数据绑定:如何将按钮命令设置为 DataTemplate 中的父 DataContext