I am having trouble with setting the BindableProperty
IconName
in a custom ContentView
in Xamarin.Forms . It is never set and stays empty. The OnPropertyChanged
method is executed for every property except the IconName
. When I change the type from enum to a string, it works as expected. What am I missing?
The OnPropertyChanged
method is needed otherwise non of the properties are set and remain their default value..
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="Peripass.Mobile.Framework.UIControls.PeripassIcon"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<ContentView.Resources>
</ContentView.Resources>
<ContentView.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Image>
<Image.Source>
<FontImageSource x:Name="_icon" Glyph="" Color="Black" Size="20" FontFamily="{OnPlatform Android=PeripassIcon.ttf#}" />
</Image.Source>
</Image>
</StackLayout>
</ContentView.Content>
</ContentView>
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Peripass.Mobile.Framework.UIControls
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PeripassIcon : ContentView
{
public static readonly BindableProperty IconSizeProperty = BindableProperty.Create(nameof(IconSize), typeof(double), typeof(PeripassIcon), 26.0);
public static readonly BindableProperty IconColorProperty = BindableProperty.Create(nameof(IconColor), typeof(Color), typeof(PeripassIcon), Color.White);
public static readonly BindableProperty IconNameProperty = BindableProperty.Create(nameof(IconName), typeof(IconType), typeof(PeripassIcon), IconType.NuclearExplosion);
public PeripassIcon()
{
InitializeComponent();
}
public IconType IconName
{
get => (IconType)GetValue(IconNameProperty);
set => SetValue(IconNameProperty, value);
}
public double IconSize
{
get => (double)GetValue(IconSizeProperty);
set => SetValue(IconSizeProperty, value);
}
public Color IconColor
{
get => (Color)GetValue(IconColorProperty);
set => SetValue(IconColorProperty, value);
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == IconNameProperty.PropertyName) {
_icon.Glyph = $"&#x{(int)IconName:X4};";
}
if (propertyName == IconColorProperty.PropertyName) {
_icon.Color = IconColor;
}
if (propertyName == IconSizeProperty.PropertyName) {
_icon.Size = IconSize;
}
}
}
}
<StackLayout Grid.Row="1" Grid.Column="0">
<uiControls:PeripassIcon IconName="NuclearExplosion" IconColor="#EE4022" IconSize="85.5"/>
</StackLayout>
The problem you are experiencing has to do with the fact that OnPropertyChanged
is only triggered when a property's value changes ( it is not enough for it to be set! ).
In your code you set the default value of IconName
to IconType.NuclearExplosion
. Later on, when you call the control you set
<uiControls:PeripassIcon IconName="NuclearExplosion" IconColor="#EE4022" IconSize="85.5"/>
which sets IconName
to the default value, again... so its value does not really changes, and thus OnPropertyChanged
is not triggered.
That being said, i have to mention that the "normaly" you would use bindings between BindableProperties and the counterparts in the view. For instance, you would bind the value of Color property in FontImageSource in your ContentView to BindableProperty IconColor. For details see the documentation on ContentView .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.