I don't think it's possible using the "pack" protocol scheme. This protocol is related to normalized Open Packaging Conventions specs (http://tools.ietf.org/id/draft-shur-pack-uri-scheme-05.txt for pointers). So the pack uri points to the application package's resources (or parts in OPC terms), not to .NET embedded resources.
However, you can define your own scheme, for example "resx" and use it in WPF component uris. New Uri schemes for such usages can be defined using WebRequest.RegisterPrefix.
Here is an example based on a small Wpf application project named "WpfApplication1". This application has a Resource1.resx file defined (and possibly other localized corresponding Resource1 files, like Resource1.fr-FR.resx for french for example). Each of these ResX files define an Image resource named "img" (note this name is not the same as the image file name the resource is based on).
Here is the 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>
The uri format is this:
resx://assembly name/resource set name/resource name
and assembly name is optional, so
resx:///resource set name/resource name
is also valid and point to resources in the main assembly (my sample uses this)
This is the code that supports it, in App.xaml.cs or somewhere else, you need to register the new scheme:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
ResXWebRequestFactory.Register();
base.OnStartup(e);
}
}
And the scheme implementation:
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;
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…