我认为不可能使用“pack”协议方案。该协议与规范化的开放包装约定规范相关(http://tools.ietf.org/id/draft-shur-pack-uri-scheme-05.txt用于指针)。因此,pack uri 指向应用程序包的资源(或 OPC 术语中的部分),而不是 .NET 嵌入式资源。
但是,您可以定义自己的方案,例如“resx”并在 WPF 组件 uris 中使用它。可以使用WebRequest.RegisterPrefix定义用于此类用途的新 Uri 方案。
这是一个基于名为“WpfApplication1”的小型 Wpf 应用程序项目的示例。此应用程序定义了一个 Resource1.resx 文件(可能还有其他本地化的相应 Resource1 文件,例如法语的 Resource1.fr-FR.resx)。这些 ResX 文件中的每一个都定义了一个名为“img”的图像资源(请注意,此名称与资源所基于的图像文件名不同)。
这是 MainWindow.xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Image Source="resx:///WpfApplication1.Resource1/img" />
</Window>
uri 格式是这样的:
resx://assembly name/resource set name/resource name
并且程序集名称是可选的,所以
resx:///resource set name/resource name
也是有效的并指向主程序集中的资源(我的示例使用这个)
这是支持它的代码,在 App.xaml.cs 或其他地方,您需要注册新方案:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
ResXWebRequestFactory.Register();
base.OnStartup(e);
}
}
及方案实施:
public sealed class ResXWebRequestFactory : IWebRequestCreate
{
public const string Scheme = "resx";
private static ResXWebRequestFactory _factory = new ResXWebRequestFactory();
private ResXWebRequestFactory()
{
}
// call this before anything else
public static void Register()
{
WebRequest.RegisterPrefix(Scheme, _factory);
}
WebRequest IWebRequestCreate.Create(Uri uri)
{
return new ResXWebRequest(uri);
}
private class ResXWebRequest : WebRequest
{
public ResXWebRequest(Uri uri)
{
Uri = uri;
}
public Uri Uri { get; set; }
public override WebResponse GetResponse()
{
return new ResXWebResponse(Uri);
}
}
private class ResXWebResponse : WebResponse
{
public ResXWebResponse(Uri uri)
{
Uri = uri;
}
public Uri Uri { get; set; }
public override Stream GetResponseStream()
{
Assembly asm;
if (string.IsNullOrEmpty(Uri.Host))
{
asm = Assembly.GetEntryAssembly();
}
else
{
asm = Assembly.Load(Uri.Host);
}
int filePos = Uri.LocalPath.LastIndexOf('/');
string baseName = Uri.LocalPath.Substring(1, filePos - 1);
string name = Uri.LocalPath.Substring(filePos + 1);
ResourceManager rm = new ResourceManager(baseName, asm);
object obj = rm.GetObject(name);
Stream stream = obj as Stream;
if (stream != null)
return stream;
Bitmap bmp = obj as Bitmap; // System.Drawing.Bitmap
if (bmp != null)
{
stream = new MemoryStream();
bmp.Save(stream, bmp.RawFormat);
bmp.Dispose();
stream.Position = 0;
return stream;
}
// TODO: add other formats
return null;
}
}
}