Issue
I want to display variable Image in Xamarin Forms. I want to bind ImageSource in XAML. I have tried using IMarkupExtension as mentioned in the docs, but the limitation is I need to specify whole path in the XAML itself. I want to bind ImageSource that can be varied whenever required. I don't want to specify whole path in XAML.
Here is my working XAML code:
<Image Source="{local:ImageResource MyProject.Images.photo.jpg}" />
Here is XAML the code that is not working:
<Image Source="{Binding imgSource StringFormat=local:ImageResource `MyProject.Images.{0}`" />
Solution
Microsoft doesn't provide information about Binding variable ImageSource in XAML in the official documentation. You need IValueConverter and ImageSource.FromResource() to convert string to ImageSource in order to bind variable Image.
Set your Image as Build: EmbeddedResource in Image Properties.
Here is the Extension for Converting
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
{
Debug.WriteLine("Assembly Name: " + assemblyName); // Just for reference, remove in Release mode
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;
}
}
In your XAML
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
...
xmlns:extensions="clr-namespace:MyProject.Extensions">
<ContentPage.Resources>
<extensions:EmbeddedToImageSourceConverter x:Key="imageConverter" />
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<Image Source="{Binding IconSource, Converter={StaticResource imageConverter}, ConverterParameter='MyProject.Resources.Images'}"
HeightRequest="40" WidthRequest="40" Aspect="AspectFit" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
In C# Code Behind (xaml.cs)
public string IconSource { get { return "photo.png"; } set { } }
public MainPage()
{
InitializeComponent();
BindingContext = this;
}
You can set BindingContext to your ViewModel and implement INotifyPropertyChanged which will sync IconSource image in your XAML with C# code.
Note that I am getting Intellisense error/warning at line <Image Source="{Binding IconSource, Converter={StaticResource imageConverter}, ... near starting curly brace of StaticResource imageConverter. The error says No DataContext found for Binding ". But the code is working fine. Anyone who would explain the reason for the error or would improve the sample code to remove the error are most welcome. Edit the answer if you find the cause.
Answered By - Juned Khan Momin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.