Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Custom Control BindableProperty propertyChanged not Firing

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?

XAML:

<?xml version="1.0" encoding="UTF-8" ?>
<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">
    <ContentView.Content>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="10" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Label x:Name="BulletPoint" Text="&#x2022;" />
            <Label x:Name="LabelContent" Grid.Column="1" />
        </Grid>
    </ContentView.Content>
</ContentView>

Code-behind:

[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<Span>),
            typeof(BulletPointItem),
            new ObservableCollection<Span>(),
            BindingMode.OneWay,
            propertyChanged: OnSpansChanged);

    public BulletPointItem()
    {
        InitializeComponent();
    }

    public ObservableCollection<Span> Spans
    {
        get => (ObservableCollection<Span>)GetValue(SpansProperty);
        set => SetValue(SpansProperty, value);
    }

    private static void OnSpansChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = (BulletPointItem)bindable;
        var newSpansValue = (ObservableCollection<Span>)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;
    }
}

Attempted Usage:

                            <controls:BulletPointItem>
                                <Span Text="Span 1." />
                                <Span FontAttributes="Italic" Text="Span 2." />
                            </controls:BulletPointItem>

Best Answer

Answers

Sign In or Register to comment.