0
votes

I have a collection private ObservableCollection<ImageData> imageDataList = new ObservableCollection<ImageData>(); where ImageData is a custom object. It has an attribute called fileName a string that stores full path of an image file. In my XAML code, I have a listbox with datatemplate as the following.

<ListBox Name="listBox_ImageList" Grid.ColumnSpan="3" Grid.Row="2" SelectionChanged="listBox_ImageList_SelectionChanged">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>

        <ListBox.ItemTemplate>
            <DataTemplate>
                <Image Source="{Binding fileName}" Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox, AncestorLevel=1}, Path=ActualHeight}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

After populating ImagaData objects into imageDataList, I set this.listBox_ImageList.ItemsSource = imageDataList;

However, when I run it, I don't see any images. Can you please tell me how to databind properly to a string member of an object to WPF image source?

3
do you see anything? what do you see if you comment out ListBox.ItemTemplate code (you should see [ImagaData.ToString()])?Jake Berger

3 Answers

0
votes

Set the DataContext to where the object where the ObservableCollection is located

DateContext = this;

Also instead of fileName bind it to a ImageSource Property or a BitmapImage Property and this is created using the fileName.

0
votes

To answer your question: You cannot bind the ImageSource property to a string. It works in XAML because WPF uses a default converter from string to ImageSource when you set the value in XAML. If you want to set the value with a binding or from code you need to provide an ImageSource object.

There are 2 ways to do it via binding:

The first one is presented here (the link Juan Carlos mentioned), and it involves creating a IValueConverter that will take your string and transform it to a ImageSource. I would modify the converter code presented there with this:

public sealed class StringToImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            return new BitmapImage(new Uri((string)value));
        }
        catch 
        {
            return DependencyProperty.UnsetValue;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The second option is to create your ImageSource in your ImageData class and bind directly to it.

private ImageSource _imageSource
public ImageSource ImageSource
{
  get
  {
    if (_imageSource == null)
    {
      _imageSource = new BitmapImage(new Uri(fileName), UriKind.RelativeOrAbsolute);
    }
    return _imageSource;
  }
}