stiank81
stiank81

Reputation: 25726

Wpf - relative image source path

I'm having problems setting the source for images in my Wpf application. I have an Image where the source is bound to the SourceUri property of the DataContext object, like this:

<Image Source="{Binding SourceUri}"></Image>

Now, I don't know what to set on the SourceUri property of my object. Setting the complete absolute path ("c:/etc/image.jpg") it displays nicely, but obviously I want to set the relative path instead. My images are stored in a folder Resources which is in the same folder as my application folder. In the end these images might come from anywhere, so adding them to the project really isn't an option.

I've tried the path relative to the application folder, and relative to the working path (debug-folder). Also tried using the "pack://.." syntax without luck, but read that this would not be any point doing.

Any hints on what I should try?

Upvotes: 15

Views: 75387

Answers (4)

sergiol
sergiol

Reputation: 4335

After some frustrating times trying with

 <Image Source="pack://application:,,,/{Binding ChannelInfo/ChannelImage}">

and

 <Image Source="pack://siteoforigin:,,,/{Binding ChannelInfo/ChannelImage}">

and

 <Image Source="/{Binding ChannelInfo/ChannelImage}">

I solved this implementing my own converter:

C# side:

public class MyImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string path= (string)value;

        try
        {
            //ABSOLUTE
            if (path.Length > 0 && path[0] == System.IO.Path.DirectorySeparatorChar
                || path.Length > 1 && path[1] == System.IO.Path.VolumeSeparatorChar)
                return new BitmapImage(new Uri(path));

            //RELATIVE
            return new BitmapImage(new Uri(System.IO.Directory.GetCurrentDirectory() + System.IO.Path.DirectorySeparatorChar + path));
        }
        catch (Exception)
        {
            return new BitmapImage();
        }

    }

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

XAML side:

<UserControl.Resources>
    <local:ImageConverter x:Key="MyImageConverter" />
    (...)
</UserControl.Resources>

<Image Source="{Binding Products/Image, Converter={StaticResource MyImageConverter}}">

Cheers,

Sérgio

Upvotes: 9

Holf
Holf

Reputation: 6441

There's a handy method in System.IO.Path which can help with this:

return Path.GetFullPath("Resources/image.jpg");

This should return 'C:\Folders\MoreFolders\Resources\image.jpg' or whatever the full path is in your context. It will use the current working folder as the starting point.

Link to MSDN documentation on GetFullPath.

Upvotes: 18

Nick Udell
Nick Udell

Reputation: 2501

Environment.CurrentDirectory will show you the folder the .exe is stored in (that is unless you manually set a .CurrentDirectory - but then we can assume you already know where it is).

Upvotes: 3

Mark Heath
Mark Heath

Reputation: 49522

Perhaps you could make the SourceUri property of your DataContext object a bit cleverer, and determine what the application folder is, and return an absolute path based on that. For example:

public string SourceUri
{
    get
    {
        return Path.Combine(GetApplicationFolder(), "Resources/image.jpg");
    }
}

Upvotes: 10

Related Questions