Binding image source dynamically on xamarin forms

42,765

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.

Share:
42,765

Related videos on Youtube

Mr. Developer
Author by

Mr. Developer

Updated on July 09, 2022

Comments

  • Mr. Developer
    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
      Alessandro Caliaro about 7 years
      do you use INotifyPropertyChanged? you should set SomeImage = "xxx.png", not someImage...
    • Emad
      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
    Mr. Developer about 7 years
    is also in respective projects
  • Mr. Developer
    Mr. Developer about 7 years
    how to change the image source ? Beach will not change from binding with your example
  • Gerald Versluis
    Gerald Versluis about 7 years
    You can declare your image like this: <Image> <Image.Source> <FileImageSource File="{Binding Img}" /> </Image.Source> </Image> and then supply a ImageSource as binding like this: public ImageSource Image { get { return ImageSource.FromResource(string.Format("Touchretail.Trims.Mo‌​bile.Images.{0}", IconSource)); } }
  • Richard Pike
    Richard Pike over 6 years
    I'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
    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
    Richard Pike over 6 years
    There must be some subtle difference I'm not seeing then. strings aren't working for me but returning the image source does :)
  • Maverick
    Maverick over 6 years
    I assume you've not set it up like I have above with <FileImageSource>
  • Zoli
    Zoli over 6 years
    This should be the accepted answer, it works like a charm!
  • jlo-gmail
    jlo-gmail about 6 years
    When using .Net Std projject I needed to use: var assembly = Assembly.GetExecutingAssembly(); var imageSource = ImageSource.FromResource(Source, assembly);
  • Gerald Versluis
    Gerald Versluis about 6 years
    Although I would recommend this, it is not absolutely necessary
  • Pxaml
    Pxaml about 4 years
    can you define the name of the images , other property is the image name ? suffix is one of them , Iam correct?
  • Maverick
    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
    Jon doe over 3 years
    if I have a class for Contacts with SomeImage as a member, then how do i set OtherProperty? I am new to xamarin
  • Maverick
    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
    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
    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
    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 as null and thus it looks for prefix--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
    user1034912 about 3 years
    'ImageSource.FromResource' does not load the image
  • user1034912
    user1034912 about 3 years
    This does not work, the Image source is a URL!
  • George McKibbin
    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
    Le Mot Juiced about 3 years
    I'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?