Search code examples
c#xamlxamarinxamarin.formsxamarin.forms.listview

How to Bind Local Embedded Image in ListView in Xamarin Forms?


I have a ListView in XAML and a List<string> that holds local embedded image paths. I am not able to show images in List. By the way I am able to show as a single image by

<Image Source="{local:ImageResource TypingApplication.Images.Icons.Search.png}" />

But I cannot show the images in ListView. Here is my XAML code

<ListView x:Name="ListView"
            ItemsSource="{Binding ListItems}"
            IsEnabled="True"
            IsVisible="True"
            RowHeight="40"
            Opacity="0.9">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>                            
                <Image Source="{local:ImageResource TypingApplication.Images.Icons.{Binding .}}"/>
            </ViewCell>                        
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

I have added ImageResourceExtension in Extensions folder and xmlns:local="clr-namespace:TypingApplication.Extensions" in XAML, as I mentioned I can show Single Image, only there is problem with ListView.

Here is my C# code that contains List and Constructor

public List<string> ListItems
{
    get
    {
        return new List<string>()
        {
            "Home.png",
            "Favorite.png",
            "Search.png"
        };
    }
}

public HomePage()
{
    InitializeComponent();
    this.BindingContext = this;
}

Please note that I am using shared Images in my project. I have set Properties of all Images to Embedded resource in SolutionExplorer.


Solution

    • Change list to ObservableCollection
    • IValueConverter implementation to convert your binding to desired value
    • The image property should be set to EmbeddedResource
    public class EmbeddedToImageSourceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string fileName && parameter is String assemblyName)
            {
                try
                {
                    var imageSource = ImageSource.FromResource(assemblyName + "." + fileName, typeof(EmbeddedToImageSourceConverter).GetTypeInfo().Assembly);
                    return imageSource;
                }
                catch (Exception)
                {
                    return value;
                }
            }
            else
                return value;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
    }
    

    XAML

    <ContentPage.Resources>
        <local:EmbeddedToImageSourceConverter x:Key="converter" />
    </ContentPage.Resources>
    

    In the listview add binding w.r.to converter resource we just created.

    <Image Source="{Binding ., Converter={StaticResource converter}, ConverterParameter='TypingApplication.Images.Icons'}" />
    

    If you are not using View Model (MVVM), you can directly specify image file's name in XAML as:

    <Image Source="{Binding Source='ImageFileName.png', Converter={StaticResource converter}, ConverterParameter='TypingApplication.Images.Icons'}" />