Reputation: 221
I am attempting to bind Image.Source in a DataTemplate to a System.Drawing.Image as discussed here: 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>
The GameTile object has an Image (not a system.drawing.image) property that points to a Picture object which has an Image property of type System.Drawing.Image. I am binding the ItemsSource on the ListBox to a GameTiles Collection on a Game object.
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); }
}
}
The images are not showing up in the ListBoxItems, but any other property that I bind to in the DataTemplate will show up. It may be worth noting that I am using Devexpress Xpo as an ORM. Also the classes represented above do implement INotifyPropertyChanged. Any thoughts on what I may be missing?
EDIT: Forgot to mention that I have implemented a value converter as mentioned in the post that I linked to above. However, if I put a breakpoint in the converter method, it is never called.
EDIT: Added the fFile property to the code above. I can set an Image.Source to the GameTile.Image.Image property through c#(by converting it to BitmapImage), and have it work as expected, but I'm not sure how to accomplish that with a DataTemplate through c#. I would prefer to set the binding in XAML, but would settle for a c# workaround with a DataTemplate (or something else that would work). I am pretty confident that the issue is not with the GameTile.Image property pulling image from the database because if I manually set the source on an Image.Source in c#, the image is there. It simply isn't working in the DataTemplate.
Edit: Determined the issue to be related to properties that are not directly on the DataType that I am binding to for example with and GameTile has a (int)PointValue property, a (Picture object)Image property, and a (Prize object)Prize property.
If I bind to
<TextBlock Text="{Binding PointValue}" />
it works as expected. But if I bind to
<TextBlock Text="{Binding Prize.Name}" />
it does not work. And If I bind to
<Image Margin="0,5,0,0" Source="{Binding Image.BitmapImage}" />
it fails also. The following graphic shows the error that is being thrown by the binding.
BindingExpression path error: 'Name' property not found on 'object' ''XPCollection' (Hash=...)'. BindingExpression:Path=Prize.Name; DataItem=GameTile' (HashCode=...); target element is 'TextBlock'(Name=''); target property is 'Text' (type 'String')
Thanks, Eric
Upvotes: 1
Views: 4220
Reputation: 221
Found the solution. Had to change this:
<TextBlock Text="{Binding Prize.Name}" />
to this:
<TextBlock Text="{Binding Prize!.Name}" />
The only difference is the exclamation point(!). This also worked for the image property.
<Image Margin="0,5,0,0" Source="{Binding Path=Image!.Image, Converter={StaticResource imageConverter}}" />
Upvotes: 1