title: Xamarin Forms Custom Control BindableProperty propertyChanged not Firing
body: <p>Trying to set up a very simple custom control to handle alignment when using bullet points in a label. The issue is, the Spans passed into the custom control are not being recognized and the content isn't getting rendered (and the propertyChanged function isn't firing). What am I missing?</p>
  
  <p>XAML:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
  &lt;ContentView
      x:Class="Sample.Controls.BulletPointItem"
      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"&gt;
      &lt;ContentView.Content&gt;
          &lt;Grid&gt;
              &lt;Grid.RowDefinitions&gt;
                  &lt;RowDefinition Height="Auto" /&gt;
              &lt;/Grid.RowDefinitions&gt;
              &lt;Grid.ColumnDefinitions&gt;
                  &lt;ColumnDefinition Width="10" /&gt;
                  &lt;ColumnDefinition Width="*" /&gt;
              &lt;/Grid.ColumnDefinitions&gt;
              &lt;Label x:Name="BulletPoint" Text="&amp;#x2022;" /&gt;
              &lt;Label x:Name="LabelContent" Grid.Column="1" /&gt;
          &lt;/Grid&gt;
      &lt;/ContentView.Content&gt;
  &lt;/ContentView&gt;
  </code></pre>
  
  <p>Code-behind:</p>
  
  <pre><code>[ContentProperty(nameof(Spans))]
  public partial class BulletPointItem : ContentView
  {
      // todo add bindable props for bullet point size and color, or even which character to use as the bullet point!
      public static readonly BindableProperty SpansProperty =
          BindableProperty.Create(
              nameof(Spans),
              typeof(ObservableCollection&lt;Span&gt;),
              typeof(BulletPointItem),
              new ObservableCollection&lt;Span&gt;(),
              BindingMode.OneWay,
              propertyChanged: OnSpansChanged);
  
      public BulletPointItem()
      {
          InitializeComponent();
      }
  
      public ObservableCollection&lt;Span&gt; Spans
      {
          get =&gt; (ObservableCollection&lt;Span&gt;)GetValue(SpansProperty);
          set =&gt; SetValue(SpansProperty, value);
      }
  
      private static void OnSpansChanged(BindableObject bindable, object oldValue, object newValue)
      {
          var control = (BulletPointItem)bindable;
          var newSpansValue = (ObservableCollection&lt;Span&gt;)newValue;
          var formattedString = new FormattedString();
  
          if (control == null)
              return;
  
          if (newSpansValue == null || newSpansValue.Count == 0)
          {
              control.LabelContent.FormattedText = formattedString;
              return;
          }
  
          foreach (var span in newSpansValue)
          {
              formattedString.Spans.Add(span);
          }
  
          control.LabelContent.FormattedText = formattedString;
      }
  }
  </code></pre>
  
  <p>Attempted Usage:</p>
  
  <pre><code>                            &lt;controls:BulletPointItem&gt;
                                  &lt;Span Text="Span 1." /&gt;
                                  &lt;Span FontAttributes="Italic" Text="Span 2." /&gt;
                              &lt;/controls:BulletPointItem&gt;
  </code></pre>