Why am I getting an IOException when I try to use an image file that was added to the project as a reference?

I have one IValueConverter

in WPF that converts a relative file path.

Code:

public class RelativeImagePathToImage : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var relativePath = (string)value;
        if (string.IsNullOrEmpty(relativePath)) return Binding.DoNothing;
        var path = "pack://application:,,,/" + value;
        var uri = new Uri(path);
        return new BitmapImage(uri);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

      

Problem:

This converter worked fine until I tried to use it with a file that was added to the project as a link (Solution Explorer -> Add existing item -> Add as a link). The image file is BuildAction

set to Content

, and the file is checked Copy Always

. The file is definitely copied to the "bin" folder correctly, but for some reason the converter chokes when it comes to return new BitmapImage(uri)

.

An exception:

System.IO.IOException was unhandled
Message="Cannot locate resource 'images/splash.png'."
Source="PresentationFramework"

      

Questions:

Can someone explain this? Is this a bug in the .NET Framework or is this expected behavior? Is there a workaround or "Add as link" rather than an option for image files?

Edit:

Ok I found a workaround. Here's my revised converter class:

public class RelativeImagePathToImage : IValueConverter
{
    private static string _rootPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var relativePath = (string)value;
        if (string.IsNullOrEmpty(relativePath)) return Binding.DoNothing;
        var path = _rootPath + "/" + relativePath;
        var uri = new Uri(path);
        return new BitmapImage(uri);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

      

Apparently there is some kind of usage issue packuri

with the linked file. But why?

+2


source to share


2 answers


The answer is in use pack://siteoforigin:,,,/

, not pack://application:,,,/

.

pack://siteoforigin

works with any content file that is copied to the bin / Debug or bin / Release folder (or any subfolder inside), regardless of whether the file was added to the project as a link or normally.



path://application

only works for content files that are usually added (not as a link).

+2


source


pack: // uri schema is only used for files inside resource directories where else if you just add a file or add a file as a link and set its type to "content" it only copies the file to the trash but it will not be packed to the app resource directories.



So, for a file that exists in a directory as a separate file, you cannot use the pack uri scheme, you need to use the uri file scheme, which is the normal path. This behavior is independent of whether the file is added as a link or copied, it depends on how the file is exported.

+1


source







All Articles