简体   繁体   中英

OnPropertyChanged not being triggered when BindableProperty is set

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.


WARNING

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM