6

I am trying to load some BitmapImages from files held on the file system. I have a dictionary of keys and relative filepaths. Unfortunately the Uri constructor seems non deterministic in the way that it will load the images.

Here is my code:

foreach(KeyValuePair<string, string> imageLocation in _imageLocations)
{
    try
    {
        BitmapImage img = new BitmapImage();
        img.BeginInit();
        img.UriSource = new Uri(@imageLocation.Value, UriKind.Relative);

        img.EndInit();
        _images.Add(imageLocation.Key, img);
    }
    catch (Exception ex)
    {
        logger.Error("Error attempting to load image", ex);

    }
}

Unfortunately sometimes the Uris get loaded as relative file Uris and sometimes they get loaded as relative Pack Uris. There doesn't seem to be any rhyme or reason as to which will get loaded which way. Sometimes I get all the Uris loading one way, or just a couple, or most of them, and it will change each time I run the code.

Any ideas what is going on here?

Oscar Mederos
  • 29,016
  • 22
  • 84
  • 124

2 Answers2

3

Well, sort of... MSDN has this to say about the UriKind:

Absolute URIs are characterized by a complete reference to the resource (example: http://www.contoso.com/index.html), while a relative Uri depends on a previously defined base URI (example: /index.html)

If you jump into reflector and look around you can see that there are lots of paths for the code to take to resolve what the relative URI should be. Anyhow, it isn't that its non-deterministic, it's more that it is just a major source of frustration for many developers. One thing that you can do is emply the 'BaseUriHelper' class to get to the bottom of how your uris are being resolved.

On the other hand, if you know where your resources are being stored (and you should) I would suggest that you just spare yourself the headache and use an absolute URI to resolve your resources. Works every time, and no goofy code behind the scenes to trip you up when you least expect it.

A.R.
  • 15,405
  • 19
  • 77
  • 123
1

In the end I solved the problem by getting the base Directory of my app and appending the relative path to that and using an absolute URI rather than a relative one.

string baseDir = AppDomain.CurrentDomain.BaseDirectory;

foreach(KeyValuePair<string, string> imageLocation in _imageLocations)
{
    try
    {
        BitmapImage img = new BitmapImage();
        img.BeginInit();
        img.UriSource = new Uri("file:///" + baseDir + @imageLocation.Value, UriKind.Absolute);

        img.EndInit();
        _images.Add(imageLocation.Key, img);
    }
    catch (Exception ex)
    {
        logger.Error("Error attempting to load image", ex);

    }
}
  • You should try Path.Combine(string, string). http://msdn.microsoft.com/en-us/library/system.io.path.combine.aspx – Francisco Apr 28 '11 at 16:09