Warum erhalte ich eine IOException, wenn ich versuche, eine Bilddatei zu verbrauchen, das das Projekt als Link hinzugefügt wurde?
-
07-07-2019 - |
Frage
Ich habe eine IValueConverter
in WPF, die einen relativen Dateipfad zu einem BitmapImage
umwandelt.
Der 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;
}
}
Das Problem:
Dieser Konverter funktioniert ganz gut, bis ich versuchte es mit einer Datei zu verwenden, die das Projektes als Link hinzugefügt wurde (Lösung Explorer -> Vorhandenes Element hinzufügen -> As-Link). Die BuildAction
die Bilddatei wird auf Content
, und die Datei wird Copy Always
markiert. Die Datei wird auf jeden Fall immer richtig auf den Ordner „bin“ kopiert, aber aus irgendeinem Grund, Drosseln der Konverter, wenn es return new BitmapImage(uri)
wird zu.
Die Ausnahme:
System.IO.IOException was unhandled
Message="Cannot locate resource 'images/splash.png'."
Source="PresentationFramework"
Fragen:
Kann das jemand erklären? Ist das ein Fehler in dem .NET Framework oder ist es das erwartete Verhalten? Gibt es eine Abhilfe oder „As-Link“ nicht nur eine Option für die Bildinhaltsdateien?
Edit:
Okay, fand ich eine Abhilfe. Hier ist meine überarbeitete Konverter-Klasse:
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;
}
}
Offenbar gibt es eine Art von Problem mit einer packuri
mit einer verknüpften Datei. Aber warum?
Lösung
Die Antwort ist pack://siteoforigin:,,,/
zu verwenden, anstatt pack://application:,,,/
.
pack://siteoforigin
funktioniert mit jeder Content-Datei, die mit dem ist / Debug oder ist / Release-Ordner (oder ein Unterordner innerhalb) kopiert wird, ob die Datei in das Projekt als Link oder normalerweise hinzugefügt wurde.
path://application
funktioniert nur für Content-Dateien, die normalerweise (nicht als Link) hinzugefügt werden.
Andere Tipps
Pack: // uri Schema ist nur für Dateien im Ressource-Verzeichnisse verwendet werden, wo sonst, wenn Sie nur eine Datei hinzufügen oder eine Datei als Link hinzufügen und dessen Typen auf „Inhalt“ es wird nur die Datei in Ihrem ist kopieren Ordner, aber es wird nicht in Anwendung Ressourcen-Verzeichnisse gepackt werden.
Also für die Datei, die im Verzeichnis als einzelne Datei vorhanden ist, können Sie nicht Pack uri Schema verwenden können, müssen Sie Datei uri Schema verwenden, die die normale Weg. Dieses Verhalten ist nicht abhängig, wenn die Datei als Link oder kopiert hinzugefügt wird, hängt davon ab, wie die Datei exportiert wird.