Little Tips: What you should do with ImageResourceExtension

Contenido

When talking about embedded resources or images to use in our XAML we usually use an extension commonly called ImageResourceExtension. I think most of you have used this extension, not to say all of you. But there’s a problem, which I want to tell you about in this new series.

That’s right, this is the first article in the new series or section called Little Tips. This series will center on small tips focused on day-to-day productivity.

I am already advancing that on many occasions they are very simple things, so simple that I even feel sorry for sharing them. Of course, everyone who knows something and has time in that area assumes that everyone else knows it too, but if you do consulting and training services you realize that things aren’t the way you thought.

This series is born from there because I often find it loose to have to talk about the same thing. And if we can have a dictionary with all these little tips, better than better, right?

I don’t mess up anymore, let’s start with our first tip for ImageResourceExtension. Let’s get to it!

Embedded images in XAML with ImageResourceExtension

When we want to use XAML-embedded images within Xamarin Forms we must make a custom XAML extension for loading these images because natively we cannot load them.

ℹ Note: To learn more about embedded images you can click here.

Everything’s perfect all the way here. Let’s look at an example:

...
[ContentProperty (nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
 public string Source { get; set; }

 public object ProvideValue (IServiceProvider serviceProvider)
 {
   if (Source == null)
   {
     return null;
   }

   // Do your translation lookup here, using whatever method you require
   var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);

   return imageSource;
 }
}
...

Having the given extension, or used all our lives, we can use it as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
   ...
   xmlns:local="clr-namespace:ProjectName.Extensions;assembly=ProjectName">

   <!-- use a custom Markup Extension -->
   <Image Source="{local:ImageResource ProjectName.FolderName.imageName.jpg}" />

</ContentPage>

So far I guess it’s all clear here, right? The thing is, I don’t know if I’m the only one who’s lazy to have to write the namespace every time I’m going to use an image.

And of course, if you work on slightly more structured projects or reuse resources between projects every time you move or reuse something you will have to change the namespace in each image. In some cases, it would be very easy to do this, in others, it’s just laziness.

Well, for those who want to save a little time on this and/or be a little more productive I have the solution for you. Let’s go!

ImageResourceExtension Tips

The truth is that there are many ways to adapt the extension depending on the needs. In my particular case, I’m going to share the one I think fits most cases.

Let’s look at an example:

...
[ContentProperty (nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
 public string Source { get; set; }

 public object ProvideValue (IServiceProvider serviceProvider)
 {
   if (Source == null)
   {
     return null;
   }

   string imagesFolderName = "Images";
   string imagePath = $"{App.Current.GetType().Namespace}.{imagesFolderName}.{Source}";

   // Do your translation lookup here, using whatever method you require
   var imageSource = ImageSource.FromResource(imagePath, typeof(ImageResourceExtension).GetTypeInfo().Assembly);

   return imageSource;
 }
}
...

In the end, it’s the same thing, all we’re doing is defining the folder where our images are located so we don’t have to define it in each image we define in our XAML. And if you handle different folders you can specify it in your XAML.

Let’s look at an example:

...
xmlns:local="clr-namespace:ProjectName.Extensions;assembly=ProjectName"
...
...

   <!-- Normal version -->
   <Image Source="{local:ImageResource ProjectName.FolderName.imageName.jpg}" />

   <!-- Tip version -->
   <Image Source="{local:ImageResource imageName.jpg}" />

   <!-- Structured version inside the images folder -->
   <Image Source="{local:ImageResource CustomFolderName.imageName.jpg}" />

...

What’s up now? Simple but powerful, isn’t it? Of course, you can adapt this and customize it to your needs or tastes.

Conclusion

Now you are 2% more productive in interface design. Isn’t it? The truth is that I would have liked this to be by default in Xamarin Forms, hopefully in #DotNetMaui let us work with the images natively, or similarly.

I hope this tip is useful to you, and if you want to share one, let me know in the comments and I would like to post it and leave you the credits. In the end, this is to help the community.

With nothing else to add, see you next time!

What do you think of this content?
 
Luis Matos

Luis Matos

I help professionals and companies to create value solutions. I am a Systems Engineer, blockchain executive, and international mobile application speaker. Founder of the Malla Consulting Agency and several international technology communities.
Subscribe
Notify of
1 Comment
Oldest
Newest
Inline Feedbacks
View all comments
1
0
Would love your thoughts, please comment.x
()
x

Search in the site