When I set the Button ImageSource property in a Setter, at runtime, when the app is starting, a Xamarin.Forms.Xaml.XamlParseException is raised:
"The PropertyName of Button.ImageSourceProperty is not ImageSource".
The exception is raised only if the code is in a ResourceDictionary inside a library.
If I put the same code in the ResourceDictionary of the Application.Resources all is ok.
Some discussions at https://forums.xamarin.com/discussion/comment/390260?
So this looks like it's caused because of this check here
The ImageSource property on Button has the PropertyName "Image" since it's just reusing the BP from ImageElement
https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Core/Button.cs#L52
That BindablePropertyConverter is only reached when adding the resource as a dictionary
One other thing to note is that the commented code here is wrong
And missing some parts
So you can just copy the XAML from here
https://github.com/DellaMoraWalter/FontImageTest/blob/master/Resources/Styles/Styles.xaml#L8
Into App.xaml
I tried using "Image" as "PropertyName". The exception is not raised but the image is not displayed anyway.
There are these questions to which I find no answer:
1) why if the style is defined in App.xaml it works both with "Image" and with "ImageSource"? In Button.cs I don't see the definition of "BindableProperty.Create ("ImageSource ", ...)". Are there some implicit conversions?
2) why should the behavior be different if the style is defined in the same way in App.xaml or in an external ResourceDictionary?
3) which parts of code do you think are missing in App.xaml?
Hi all,
I happen to ran into this issue today. After looking to the code i think that making ImageSourceProperty point to ImageElement.SourceProperty instead of ImageElement.ImageProperty should do the trick.
https://github.com/xamarin/Xamarin.Forms/blob/6d3c41fb2dc0911979cbddda4987e8f76ef7845f/Xamarin.Forms.Core/Button.cs#L54
https://github.com/xamarin/Xamarin.Forms/blob/719fc7a604ff0cce8922d717c99bfb0fa17e35e0/Xamarin.Forms.Core/ImageElement.cs#L11-L12
Do you think this will work?
Hi again,
I've created a quick workaround for this problem using a AttachedProperty.
I've used a FontImageSource as type because this is what i needed but you can off course change this to your own needs.
public static class ButtonExtension
{
public static BindableProperty FontImageSourceProperty =
BindableProperty.CreateAttached("FontImageSource", typeof(FontImageSource),
typeof(ButtonExtension), null, propertyChanged: HandleChanged);
public static FontImageSource GetFontImageSourceProperty(BindableObject view)
{
return (FontImageSource)view.GetValue(FontImageSourceProperty);
}
public static void SetFontImageSourceProperty(BindableObject view, FontImageSource source)
{
view.SetValue(FontImageSourceProperty, source);
}
static void HandleChanged(BindableObject bindable, object oldValue, object newValue)
{
if (!(bindable is Button button))
return;
button.ImageSource = (FontImageSource)newValue;
}
}
And this is how i use it in a style.
<FontImageSource
x:Key="ArrowRight"
FontFamily="{StaticResource IconFontFamily}"
Glyph="{x:Static icons:IconFont.VF_arrow_right_rgb}"
Color="{StaticResource OceanBlue}"
Size="{StaticResource ButtonTextSize}" />
<Style x:Key="LinkButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="extensions:ButtonExtension.FontImageSource" Value="{StaticResource ArrowRight}" />
<Setter Property="Padding" Value="0" />
</Style>
Hope this helps someone with the same problem.
I used SvgImageSource from XamSvg, when set through a style it only works with ImageButton.Source. It never work with Button.ImageSource.
If you set it directly (not through a style) it does work.
Platform: Android 10. Xamarin Forms 4.8.
Might also be the reason why I'm not able to get this MarkupExtension to work on a Button, while it works fine on an ImageButton and a regular Image.
This is the implementation I've made so far.
```C#
[ContentProperty(nameof(ImageSource))]
public class SvgOnButtonResourceExtension : IMarkupExtension
{
public string ImageSource { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (ImageSource == null)
{
return null;
}
var width = 0;
var height = 0;
IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
var visualElement = provideValueTarget.TargetObject as VisualElement;
if (visualElement != null)
{
width = (int)visualElement.WidthRequest;
height = (int)visualElement.HeightRequest;
}
var imageSource = SvgImageSource.FromResource(ImageSource, typeof(SvgOnButtonResourceExtension).GetTypeInfo().Assembly, width, height);
return imageSource;
}
}
```XAML
xmlns:utilities="clr-namespace:My.App.Utilities;assembly=My.App"
...
<Button WidthRequest="200"
HeightRequest="200"
HorizontalOptions="Center"
VerticalOptions="Center"
ImageSource="{utilities:SvgOnButtonResource My.App.Resources.sample.svg}"
ContentLayout="Top, 10" />
Since the Image property was already deprecated in Xamarin Forms 4, would it be a solution to just remove the Image-property all together in Xamarin Forms 5?
The obsolete warning is no longer needed and when that is out of the way (and with the property name matching), the bindable property conversion will nog longer stop processing. Could be the fix to the problem of @PureWeen .
Not sure if that fixes the issue @softlion and I are facing. We should do some more investigation on that to see if the issues are the same.
Most helpful comment
Hi again,
I've created a quick workaround for this problem using a AttachedProperty.
I've used a FontImageSource as type because this is what i needed but you can off course change this to your own needs.
And this is how i use it in a style.
Hope this helps someone with the same problem.