C# 将pack://URI转换为相对URI

C# 将pack://URI转换为相对URI,c#,wpf,xaml,serialization,C#,Wpf,Xaml,Serialization,在使用XamlWriter进行序列化的过程中,我尝试序列化Image控件。这些控件的这些Source属性设置为相对URI 但是,在使用XamlWriter进行序列化之后,Image控件包含如下路径: <d:ImageData ImageSourceUri="test_local.png" /> 原始路径 XamlWriter路径 有没有什么方法可以防止XamlWriter将相对路径更改为打包路径?经过多次尝试和错误,我想出了一个解决方案,我想与大家分享 我创建了一个新类,Image

在使用
XamlWriter
进行序列化的过程中,我尝试序列化
Image
控件。这些控件的这些
Source
属性设置为相对URI

但是,在使用
XamlWriter
进行序列化之后,
Image
控件包含如下路径:

<d:ImageData ImageSourceUri="test_local.png" />
原始路径

XamlWriter路径


有没有什么方法可以防止
XamlWriter
将相对路径更改为打包路径?

经过多次尝试和错误,我想出了一个解决方案,我想与大家分享

我创建了一个新类,
ImageData
来封装我需要加载到
Image
控件中的相对Uri

public class ImageData
{
    /// <summary>
    /// Relative path to image
    /// </summary>
    public string ImageSourceUri { get; set; }

    public ImageSource ImageSource
    {
        get { return new BitmapImage(App.GetPathUri(ImageSourceUri)); }
    }
}
最后,为了方便起见,我在XAML中创建了一个
DataTemplate
,同样在App.XAML文件中:

<Application.Resources>
    <DataTemplate DataType="{x:Type local:ImageData}">
        <Image Source="{Binding Path=ImageSource}"></Image>
    </DataTemplate>
</Application.Resources>

因此路径被存储为相对路径,类型为
string
,然后当使用
XamlReader.Load
再次加载XAML时,DataTemplate绑定到
ImageSource
属性,该属性会尽可能晚地将相对路径转换为绝对路径。

检查这个问题:作为旁注,是否将GetPath逻辑放置在App类中是一个设计考虑因素-根据上下文,将其作为ImageData类中的私有方法放置可能会减少耦合。。
    /// <summary>
    /// Converts a relative path from the current directory to an absolute path 
    /// </summary>
    /// <param name="relativePath">Relative path from the current directory</param>
    public static string GetPath(string relativePath)
    {
        return System.IO.Path.Combine(Environment.CurrentDirectory, relativePath);
    }

    /// <summary>
    /// Converts a relative path from the current directory to an absolute Uri 
    /// </summary>
    /// <param name="relativePath">Relative path from the current directory</param>
    public static Uri GetPathUri(string relativePath)
    {
        return new Uri(GetPath(relativePath), UriKind.Absolute);
    }
<Application.Resources>
    <DataTemplate DataType="{x:Type local:ImageData}">
        <Image Source="{Binding Path=ImageSource}"></Image>
    </DataTemplate>
</Application.Resources>
<d:ImageData ImageSourceUri="test_local.png" />