2009-09-16 3 views
2

У меня есть IValueConverter в WPF, который преобразует относительный путь к файлу BitmapImage.Почему я получаю IOException, когда пытаюсь использовать файл изображения, который был добавлен в проект в качестве ссылки?

Кодекс:

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; 
    } 
} 

Проблема:

Этот конвертер работает прекрасно, пока я не пытался использовать его с файлом, который был добавлен в проект в качестве ссылки (Обозреватель решений -> Добавить существующий элемент -> Добавить как ссылку). Файл изображения BuildAction установлен в Content, а файл отмечен Copy Always. Файл определенно правильно скопирован в папку «bin», но по какой-то причине преобразователь задыхается, когда он достигает return new BitmapImage(uri).

за исключением:

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

Вопросы:

Может кто-нибудь объяснить это? Является ли это ошибкой в ​​.NET Framework или это ожидаемое поведение? Есть ли обходной путь или «Добавить как ссылка», а не вариант для файлов с изображениями?

Edit:

Хорошо, я нашел обходной путь. Вот мой пересмотренный конвертер класс:

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; 
    } 
} 

По-видимому, есть какие-то проблемы с использованием packuri с связанного файла. Но почему?

ответ

2

Ответ заключается в использовании pack://siteoforigin:,,,/, а не pack://application:,,,/.

pack://siteoforigin работает с любым файлом содержимого, который копируется в папку bin/Debug или bin/Release (или любую подпапку внутри), независимо от того, был ли файл добавлен в проект как ссылка или обычно.

path://application работает только с файлами контента, которые обычно добавляются (а не как ссылка).

1

pack: // uri-схема используется только для файлов внутри каталогов ресурсов, где else, если вы просто добавляете файл или добавляете файл в качестве ссылки и устанавливаете его тип в «контент», он копирует только файл в вашем bin, но он не будет упакован в каталоги ресурсов приложений.

Так что для файла, который существует в каталоге как отдельный файл, вы не можете использовать схему пака uri, вам нужно использовать схему файлов uri, которая является нормальным путем. Это поведение не зависит от того, добавлен ли файл в качестве ссылки или скопирован, он зависит от того, как экспортируется файл.

+0

Но код отлично работает для файла изображения, помещенного в папку, и устанавливается в 'Content' -' Copy Always'. Он переставал работать, когда я использовал ссылку вместо сохранения файла в папке. – devuxer

+0

+1, Этого было достаточно, чтобы решить мой случай: Файлы одной папки проекта deep = отлично работали. Две папки проекта deep = exception. Смешной. –