Xamarin.forms: Bindings in span are not working

Created on 17 Aug 2018  Â·  9Comments  Â·  Source: xamarin/Xamarin.Forms

Description

I have an span in wich I'm trying to bind values. I'm following the steps provided in this link: https://github.com/xamarin/Xamarin.Forms/issues/1340
PD: I created a property in my ViewModel wich implements INotifyPropertyChanged.

Expected Behavior

Be able to bind values to span

Actual Behavior

Values are not reflected in span

Basic Information

  • Version with issue:
  • IDE: Visual Studio 2017 for Windows
  • Android: 7.1
  • Xamarin forms 3.1.0.697729

Reproduction Link

My XAML:
<Label HorizontalOptions="EndAndExpand" Grid.Column="1"> <Label.FormattedText> <FormattedString> <Span Text="{Binding ListCount}"/> <Span Text="/"/> <Span Text="15"/> </FormattedString> </Label.FormattedText> </Label>

Xaml </> binding ⛓

Most helpful comment

This is a huge gotcha and should be documented in caps lock 😅

All 9 comments

i have same problem.Please help

Same problem @adamped

I'm able to bind properties which exists, but I don't think properties are updating even when OnPropertyChanged() is fired.

Example:

new Label { FormattedText = new FormattedString { Spans = { new Span { Text = "Status: ", FontAttributes = FontAttributes.Bold, FontSize = 17, ForegroundColor = Color.FromHex("A0A0A0") }, new Span { FontSize = 17, ForegroundColor = Color.FromHex("A0A0A0") }.Bind("OrderItem.status") } } },
                                    new Label { FormattedText = new FormattedString { Spans = { new Span { Text = "Dispatch Date: ", FontAttributes = FontAttributes.Bold, FontSize = 17, ForegroundColor = Color.FromHex("A0A0A0") }, new Span { ForegroundColor = Color.FromHex("A0A0A0"), FontSize = 17 }.Bind("OrderItem.dispatchTime") } } }.Bind(IsVisibleProperty, "DeliveredStatus", BindingMode.OneWay, new InverseBoolConverter()),
                                    new Label { FormattedText = new FormattedString { Spans = { new Span { Text = "Last Location: ", FontAttributes = FontAttributes.Bold, FontSize = 17, ForegroundColor = Color.FromHex("A0A0A0") }, new Span { ForegroundColor = Color.FromHex("A0A0A0"), FontSize = 17 }.Bind(Span.TextProperty, "LastLocationSpan") } } }.Bind(IsVisibleProperty, "DeliveredStatus", BindingMode.OneWay, new InverseBoolConverter()),
                                    new Label { FormattedText = new FormattedString { Spans = { new Span { Text = "ETA: ", FontAttributes = FontAttributes.Bold, FontSize = 17, ForegroundColor = Color.FromHex("A0A0A0") }, new Span { ForegroundColor = Color.FromHex("A0A0A0"), FontSize = 17 }.Bind("ETASpan") } } }.Bind(IsVisibleProperty, "DeliveredStatus", BindingMode.OneWay, new InverseBoolConverter()),

The first two items from "OrderItem" already have a value, so it shows. LastLocation and ETASpan don't display because this data is downloaded and needs to update when data is downloaded.

See also: https://github.com/xamarin/Xamarin.Forms/pull/3452
LineHeights are broken for spans on UAP.

Spans bindings are OneTime.

change your bindings to

<Span Text="{Binding ListCount, Mode=OneWay}"/>

I believe that span binding that are default OneTime is a bug.
As a developer I am used to have changes notified to the UI. For some reason, only this Span default binding mode is different, and I can't find any documentation on it anywhere. Only this thread reveals that it is default OneTime.
Why not make it OneWay? For optimization, the developer can change it to OneTime?

@StephaneDelcroix is OneTime by design? If so, I think it'd be prudent to ensure it's well documented since it _is_ a deviation from the way Text is setup.

@ChaseFlorell it is by design. OneTime bindings are way cheaper than OneTime. I'm putting things in motion so the docs gets updated

This is a huge gotcha and should be documented in caps lock 😅

I just came across this issue in a 3.1 app I maintain. I tested the span binding in the latest version (4.0.0.497661) and it looks like they are now listening to binding changes (woo). Unfortunately that doesn't fix my old app... (and theres no chance of upgrading to 4)

So for anyone interested I have a quick & angry hack to chuck at your code to get spans binding after initialisation, the way you would expect...

In your code behind ctor:

INotifyPropertyChanged vm = (INotifyPropertyChanged)this.BindingContext;
vm.PropertyChanged += Vm_YourPropertyChanged;

Somewhere in the codebehind class:

void Vm_CurrentViewPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (!e.PropertyName.Equals("YourProperty"))
        return;

    var yourProperty = ((YourViewModel)sender).YourProperty;
    BindableSpan.Text = yourProperty; //Make sure you give your span an x:Name
}
Was this page helpful?
0 / 5 - 0 ratings