Introduction
If you need to make an application which uses many non vector graphics (button or menu icons, window icons), it is difficult to use 'pack' syntax, it makes the code difficult and big. Of course, there are some workarounds with using static keys, but they are all too complicated. I think I have a good and convenient solution...
I will not show examples of difficult usage, you can find them on the internet, or maybe you use them just always. Just a solution...
Using the Code
All that we need is to create a resource assembly and write a simple markup extension R
:
[ContentProperty("ResourceKey")]
[MarkupExtensionReturnType(typeof(ImageSource))]
public class R : MarkupExtension
{
public String ResourceKey { get; set; }
public Object Resource { get; set; }
public R(string resourceKey)
{
ResourceKey = resourceKey;
Resource = TryGetImageSource(resourceKey);
}
private static readonly Dictionary<String,
ImageSource> _imagesSources = new Dictionary<string, ImageSource>();
public static ImageSource TryGetImageSource(String resourceKey)
{
ImageSource result;
if (_imagesSources.TryGetValue(resourceKey, out result))
{
return result;
}
try
{
result = new BitmapImage(new Uri
(@"pack://application:,,,/BitmapResources;component/Resources/{0}.png".F(resourceKey)));
}
catch
{
try
{
result = new BitmapImage(new Uri
(@"pack://application:,,,/BitmapResources;component/Resources/{0}.ico".F(resourceKey)));
}
catch
{
try
{
result = new BitmapImage(new Uri
(@"pack://application:,,,/BitmapResources;component/Resources/{0}.jpg".F(resourceKey)));
}
catch
{
}
}
}
if (result != null)
{
result.Freeze();
_imagesSources[resourceKey] = result;
}
return result;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return Resource;
}
}
Please look carefully to pack paths specified in code:
pack://application:,,,/BitmapResources;component/Resources/{0}.png
Here BitmapResources
is the name of DLL with resources.
DLL with resources contain folder Resources with 2 images:
You should add images and specify build action for them as 'Resource
'.
Then, you can use new extension in your WPF project:
<Window x:Class="WPFBitmapResources.MainWindow"
xmlns:r="clr-namespace:BitmapResources;assembly=BitmapResources"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Image Source="{r:R A}" Width="50" Height="50"/>
<Image Source="{r:R B}" Width="50" Height="50"/>
<Image Source="{r:R A}" Width="100" Height="100"/>
<Image Source="{r:R B}" Width="100" Height="100"/>
</StackPanel>
</Window>
Final look in designer:
Done!
Points of Interest
Using the same technique, it is simple to use String
resources or make localizable project.
History