Xamarin.forms: Proposal: Change default binding mode of Span Text property to OneWay

Created on 27 Jun 2018  ·  2Comments  ·  Source: xamarin/Xamarin.Forms

Xamarin.Forms 3.1 introduced BindableSpan 👍.
As part of that work is was suggested that the default BindingMode be set to OneTime because OneTime bindings are cheaper.

I would like to start a discussion, and propose switching the default binding mode to be OneWay for the Span.TextProperty. There are also the other Color properties on Span as well that are currently defaulting to OneTime. I would also suggest that these be changed as well; however that is a much smaller concern.

I do realize that I can set the Mode on all of my Span's Bindings to be OneWay and get the behavior I am describing. However, this issue is not about saving a few keystrokes. It is about lost development time, trying to debug binding issues that arise from unexpected behavior.
I am also aware that there was at least one other issue raised, where this unexpected default caused a problem.

The Common Case

First I would like to make the case, that in general if I am applying a {Binding} to a Span OneWay is the most common use case. Broadly speaking there are only two common sources for the {Binding}.

  • Bind to the property on another control. I can come up with many examples where this property would be expected to change. Binding to the text of an Entry field. Binding to the selected item in a ListView. Binding to the current position of the CaroselView. Etc. I struggle to come up with very many cases where I am using a Binding to effectively link two pieces of text. For most of those situations, I would merely put the shared text as a resource (referenced with StaticResource) and avoid a Binding altogether.
  • Bind to a property on a BindingContext (ViewModel). For the OneTime binding to be useful here, it would require that the property is populated when the object is bound, and never change. I can imagine a few use cases binding to POCO (no INotifyPropertyChanged - INPC) where this might be the case. Such as binding to model straight out of Entity Framework. There is also the possibility that the Span is used as part of a DataTemplate, in which case the object is likely populated when it is bound, and replacing the entire instance with a new one, effectively causes the view to update. However, I would propose that this is the exception case and not the rule. Binding to a POCO is nice, but the times where merely binding to its properties once are few and far between. Data needs to be updated. Data is commonly retrieved asynchronously. Simply updating a view model and raising INotifyPropertyChanged is what is expected.

Performance

Currently it looks as if the only performance gains from using BindingMode.OneTime come when compiling your XAML. I do not want to downplay the importance of compiled XAML or the performance gains from not needing to create and emit those handlers; compiled XAML is the default and I typically see it as the default starting point. However, unless I am missing something, at run time (assuming non-compiled XAML or items created in code) there is little difference between a OneWay and OneTime binding. From this perspective, the performance gains do not seem worth the loss of the time and functionality. Have I missed anything here?

Familiarity with other XAML frameworks

For what it is people familiar with other XAML frameworks will also likely expect OneWay (minimum) binding as a default. I am hesitant to use the words "XAML Standard" but the spirit of it is here. Changing the default binding mode to OneWay will align with what is already done in the other frameworks.

  • WPF Run: Defaults to TwoWay. When using within a TextBlock (the most common case) this deviates from the normal WPF behavior of TwoWay defaults for properties that can change due to user interaction, and OneWay for everything else.
  • UPW Run: In general UWP defaults {Binding} to OneWay, except in the case the TextProperty.
  • Xamarin.Forms: Prior to the new bindable Span, the only other property in the framework that defaults to OneTime is Entry.IsTextPredictionEnabledProperty. I believe this deviation from the norm in the rest of the the framework, is also contributing to the confusion.

Comparison with x:Bind

x:Bind is coming for Xamarin.Forms. With it, I would suggest, comes the opportunity to reset developer's Binding expectations. In UWP "{x:Bind} defaults to OneTime; {Binding} defaults to OneWay". Those already familiar with UWP XAML know this, and I would suggest that keeping Xamarin.Forms inline with this pattern will help meet developer's expectations.

Relevant parties/stakeholders

@adamped
@jassmith

enhancement ➕

Most helpful comment

I raised this issue initially as I saw this problem coming. Its hard to know that its defaulted to something different and the performance gains, are likely to be unnoticeable in most apps between OneWay and OneTime.

I'm all for setting it to OneWay.

All 2 comments

I raised this issue initially as I saw this problem coming. Its hard to know that its defaulted to something different and the performance gains, are likely to be unnoticeable in most apps between OneWay and OneTime.

I'm all for setting it to OneWay.

Agreed.
Just hit this same problem and was just about to raise this same issue.
It should be consistent with the default mode for Labels.
If the performace gain is important enough for Spans then it should be as important for Labels.
Either way, I think they should be consistent with each other.

Was this page helpful?
0 / 5 - 0 ratings