Reputation: 4336
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
.
Upvotes: 1
Views: 2109
Reputation: 9144
ObservableCollection
IValueConverter
implementation to convert your binding to desired valueEmbeddedResource
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'}" />
Upvotes: 2
Reputation: 10356
If you want to add Embedded image in listview, according to json's reply, your binding have some problem, you can use IValueConverter to convert image path as correct.
I do one sample according to your code, you can take a look:
<ListView HasUnevenRows="True" ItemsSource="{Binding ListItems}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Image
HeightRequest="100"
Source="{Binding ., Converter={StaticResource imageconverter}}"
WidthRequest="100" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ContentPage.Resources>
<local:imageconverter x:Key="imageconverter" />
</ContentPage.Resources>
The Image converter:
public class imageconverter : IValueConverter
{
public string Source { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Source = (string)value;
if (Source == null)
return null;
// Do your translation lookup here, using whatever method you require
var imageSource = ImageSource.FromResource("demo3."+Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);
return imageSource;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
You can change demo3 as TypingApplication according to your code.
public partial class Page14 : ContentPage
{
public ObservableCollection<string> ListItems { get; set; }
public Page14()
{
InitializeComponent();
ListItems = new ObservableCollection<string>()
{
"image1.jpg","image2.png","image3.png"
};
this.BindingContext = this;
}
}
As Prateek's reply, I suggest you can change List<> to Observablecollection<>, because it implement INotifyPropertyChanged interface, notify data changed.
Upvotes: 1