Click here to Skip to main content
15,889,860 members
Articles / Desktop Programming / WPF
Tip/Trick

Simple Usage of Bitmaps in WPF XAML

Rate me:
Please Sign up or sign in to vote.
4.43/5 (3 votes)
25 Mar 2015CPOL 18.6K   125   12   9
Usage of non vector graphics in WPF application is too complicated by default, I will show how it can be simple and convenient.

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:

C#
[ContentProperty("ResourceKey")]
[MarkupExtensionReturnType(typeof(ImageSource))]
public class R : MarkupExtension
{
    /// <summary>
    /// Resource key
    /// </summary>
    public String ResourceKey { get; set; }

    /// <summary>
    /// Property to override resource if it was get haghter
    /// </summary>
    public Object Resource { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="R"/> class.
    /// </summary>
    /// <param name="resourceKey">
    /// The resource key to use to obtain the localized value.</param>
    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
                {
                    //Here you can implement retrieving any other extensions
                }
            }
        }
        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:

BitmapResources project structure.

You should add images and specify build action for them as 'Resource'.

Then, you can use new extension in your WPF project:

HTML
<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:

Final look in designher.

Done!

Points of Interest

Using the same technique, it is simple to use String resources or make localizable project.

History

  • 25/03/2015 - Created

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Saber Interactive
Russian Federation Russian Federation
My specializations:

C# (especially multithreading)
WPF (MVVM, styling)
WCF (message inspectors, configuration)
MSSQL (administartion, creation, procedures, recursive queries, bulk processing)

Comments and Discussions

 
QuestionSimple usage? Pin
Ansgar Hellwig31-Mar-15 23:42
professionalAnsgar Hellwig31-Mar-15 23:42 
AnswerRe: Simple usage? Pin
Evgeny Bestfator1-Apr-15 0:33
professionalEvgeny Bestfator1-Apr-15 0:33 
Question+3 Some Thoughts Pin
zephaneas25-Mar-15 5:32
zephaneas25-Mar-15 5:32 
AnswerRe: +3 Some Thoughts Pin
FIorian Schneidereit25-Mar-15 10:19
FIorian Schneidereit25-Mar-15 10:19 
GeneralRe: +3 Some Thoughts Pin
Evgeny Bestfator26-Mar-15 1:35
professionalEvgeny Bestfator26-Mar-15 1:35 
AnswerRe: +3 Some Thoughts Pin
Evgeny Bestfator26-Mar-15 1:43
professionalEvgeny Bestfator26-Mar-15 1:43 
AnswerRe: +3 Some Thoughts Pin
Evgeny Bestfator1-Apr-15 1:54
professionalEvgeny Bestfator1-Apr-15 1:54 
QuestionCould you please fix the images? Pin
Sven Bardos25-Mar-15 2:47
Sven Bardos25-Mar-15 2:47 
AnswerRe: Could you please fix the images? Pin
Evgeny Bestfator25-Mar-15 3:31
professionalEvgeny Bestfator25-Mar-15 3:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.