首页 文章

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

提问于
浏览
1

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

Objects

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#将Image.Source设置为GameTile.Image.Image属性(通过将其转换为BitmapImage),并使其按预期工作,但我不知道如何通过c#实现DataTemplate . 我更喜欢在XAML中设置绑定,但是可以使用DataTemplate(或其他可行的方法)解决c#变通方法 . 我非常有信心问题不在于GameTile.Image属性从数据库中提取图像,因为如果我在c#中的Image.Source上手动设置源,那么图像就在那里 . 它根本不适用于DataTemplate .

编辑:确定问题与不直接在我绑定的DataType上的属性有关,例如,和GameTile有一个(int)PointValue属性,一个(Picture对象)Image属性和一个(Prize对象)奖属性 .

如果我绑定

<TextBlock Text="{Binding PointValue}" />

它按预期工作 . 但如果我绑定

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

这是行不通的 . 如果我绑定

<Image Margin="0,5,0,0" Source="{Binding Image.BitmapImage}" />

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

BindingExpression路径错误:'对象'''XPCollection'(Hash = ...)'上找不到'Name'属性 . BindingExpression:路径= Prize.Name; DataItem = GameTile'(HashCode = ...); target元素是'TextBlock'(Name =''); target属性是'Text'(类型'String')

enter image description here

谢谢,埃里克

1 回答

  • 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}}" />
    

相关问题