Binding image source dynamically on xamarin forms
Solution 1
I'll post this answer here because it's the one I was looking for and I suspect most others are (and Google currently directs you here, which currently isn't super helpful).
How to bind an image using XAML:
XAML:
<Image>
<Image.Source>
<FileImageSource File="{Binding SomeImage}" />
</Image.Source>
</Image>
Then in the ViewModel, C#:
public string SomeImage
{
get { return string.Format("prefix-{0}-suffix.png", OtherProperty); }
}
Newer, better, but essentially equivalent c# you can use instead of the above:
public string SomeImage => $"prefix-{OtherProperty}-suffix.png";
This is certainly the easiest way to set it up, IMO :).
EDIT: It should go without saying, but the image should obviously be in the Resources
folder of the project for each platform.
EDIT2, much later: In case it's not obvious, "prefix", "suffix" are just random strings, SomeImage
just has to return the path of your image. SomeImage
and OtherProperty
are members of your view model class, OtherProperty
is just something you're basing your image name on (because if you know the whole name in advance, you don't need this question).
Solution 2
You said:
the image is in "Images" folder on portable project
Each platform have a different approach for resources and images. Xamarin handles that in every platform for example Xamarin.iOS has embedded resource while Xamarin.Android uses Android resource for images.
You should place your images in every project for Xamarin.Forms to know where to look for them in each platform.
For more information look at this.
Solution 3
For using images from the PCL, check out this part in the Xamarin documentation.
You should make sure the Build action
for each image is set to Embedded Resource
.
Then, if you want to use them in XAML, specify a MarkupExtension
[ContentProperty ("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);
return imageSource;
}
}
You should then be able to use your images like this.
<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:WorkingWithImages;assembly=WorkingWithImages"
x:Class="WorkingWithImages.EmbeddedImagesXaml">
<StackLayout VerticalOptions="Center" HorizontalOptions="Center">
<!-- use a custom Markup Extension -->
<Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
</StackLayout>
</ContentPage>
Like mentioned in the comments, if you want this to work out of the box place them in the Resources folder of your respective platform project. This way you can also leverage the auto sizing mechanisms that are in place. To read more on this method see this page.
By adding them with the right naming convention in the right folder, you can simply refer to the filename and Xamarin.Forms will translate that to the right format for the platform.
Solution 4
You can do it a bit simpler I think. This is working on mine. Put the image in the appropriate place on each platform eg. Resources/drawable on Android
In your Xaml:
<Image Source="{Binding someImage}" Aspect="Fill" Grid.Row="2"></Image>
In your View Model:
private string _someImage = "icon_eye_hidden";
public string someImage
{
get => this._someImage;
set
{
if (this._someImage == value) return;
this._someImage = value;
this.RaisePropertyChanged(() => this.someImage);
}
}
Then just set someImage to the name of the image (without the extension) and it should update.
Related videos on Youtube
Mr. Developer
Updated on July 09, 2022Comments
-
Mr. Developer almost 2 years
my question is, could I Binding string image to image source ? I have multiple image and the image will change on if condition. So:
Xaml on Xamarin forms:
<Image Source="{Binding someImage}" Aspect="Fill" Grid.Row="2"></Image>
Codebehind c#
public String someImage; public String SomeImage { set { if (someImage != value) { someImage = value; } } get { return someImage; } }
InitializeComponent part:
if(true) { someImage = "backgroundListViewGren.png"; } else { someImage = "backgroundListViewRed.png"; }
the image is in "Images" folder on portable project
but this, doesn't work, maybe i wront something but I don't understand. Any solutions ?
I've tried with ImageSource and not string, but don't work too.
-
Alessandro Caliaro about 7 yearsdo you use INotifyPropertyChanged? you should set SomeImage = "xxx.png", not someImage...
-
Emad about 7 years
the image is in "Images" folder on portable project
This will not work. You should place them in each projects respective resource location
-
-
Mr. Developer about 7 yearsis also in respective projects
-
Mr. Developer about 7 yearshow to change the image source ? Beach will not change from binding with your example
-
Gerald Versluis about 7 yearsYou can declare your image like this:
<Image> <Image.Source> <FileImageSource File="{Binding Img}" /> </Image.Source> </Image>
and then supply aImageSource
as binding like this:public ImageSource Image { get { return ImageSource.FromResource(string.Format("Touchretail.Trims.Mobile.Images.{0}", IconSource)); } }
-
Richard Pike over 6 yearsI've found you actually need to return the ImageSource in the ViewModel NOT a string: public ImageSource SomeImage => ImageSource.FromResource($"(ProjectName).Images.(ImageName)"); It also appears (at least on Android) that hyphens in the filename can not be used
-
Maverick over 6 years^^ This is strictly incorrect - you absolutely can return a string from the ViewModel. I can't comment on the hyphens in the filename though as we don't have any. In fact trying what you suggest via the method I'm explaining will I'm fairly sure simply not work at all :).
-
Richard Pike over 6 yearsThere must be some subtle difference I'm not seeing then. strings aren't working for me but returning the image source does :)
-
Maverick over 6 yearsI assume you've not set it up like I have above with
<FileImageSource>
-
Zoli over 6 yearsThis should be the accepted answer, it works like a charm!
-
jlo-gmail about 6 yearsWhen using .Net Std projject I needed to use: var assembly = Assembly.GetExecutingAssembly(); var imageSource = ImageSource.FromResource(Source, assembly);
-
Gerald Versluis about 6 yearsAlthough I would recommend this, it is not absolutely necessary
-
Pxaml about 4 yearscan you define the name of the images , other property is the image name ? suffix is one of them , Iam correct?
-
Maverick about 4 years@Pxaml I'm not quite sure what you mean. The image name can be literally whatever you want, you then just use
{Binding VariableName}
to bind to the property that gives you the image file name - but that is just a string, it can be anything.. -
Jon doe over 3 yearsif I have a class for Contacts with SomeImage as a member, then how do i set OtherProperty? I am new to xamarin
-
Maverick over 3 years@Jondoe
OtherProperty
in my example above is just some other member of the class used in the image name. So you might have:public string ContactTypeImage => $"contact-type-{ContactType}.png"
for example with<FileImageSource File="{Binding ContactTypeImage}" />
-
Jon doe over 3 years@Maverick I am so sorry for not being clear. I've a list of List<Contacts> where Name, status and ContactImage are the members and I'm setting the values in xaml.cs. Something like this but how do I set value of OtherProperty or ContactImage var ListItems = new ObservableCollection<Contacts>() { new Contacts{Name="Susana", OtherProperty="instaIMG"}, new Contacts{Name="Sara", OtherProperty="instaIMG", Status="let's tallk"} };
-
Maverick over 3 years@Jondoe do you mean your view model has a the list of Contacts? In that case you'll need a sub-view for each contact and do the binding as above, AFAIK (but I haven't used Xamarin for quite some time).
-
KamielDev about 3 years@Maverick I set it up in a similar way to your example, but running into an issue. If I hardcode my String Format to return 'prefix-chosentype-suffix.jpg` it works fine, but if I use my TypeChooserProperty to fill in the
chosentype
the image is not displayed. This is because it tries to load the image before it actually loaded the Item model data into my ItemDetailViewModel, so the property returns asnull
and thus it looks forprefix--chosentype.jpg
which doesn't exist Any way to solve that issue? It's weird because my labels for example do show the data that my Item holds. -
user1034912 about 3 years'ImageSource.FromResource' does not load the image
-
user1034912 about 3 yearsThis does not work, the Image source is a URL!
-
George McKibbin about 3 years@user1034912 I guarantee it worked at the time, but I haven't looked at Xam Forms for years. Seemed to be some sort of Xamarin binding magic behind the scenes.
-
Le Mot Juiced about 3 yearsI'm using this code all over my projects, so I can guarantee it does what it says if it's used right. It might fail in circumstances I didn't expect, of course. Can you tell me the filename you're searching for, and where it is in your project?