The Span class should have Bindable properties and the addition of a Style
property.
Make Span
Inherit from BindableObject
and support bindings on the properties. Also add a Style
property so that Spans
can be individually styled in the same way as a Label
.
eg:
<Label>
<Label.FormattedText>
<FormattedString>
<FormattedString.Spans>
<Span Text="My Label" Style="{StaticResource title-style}" />
<Span Text="{Binding Info}" Style="{StaticResource text-style}" />
<Span Text="{Binding Sum}" Style="{StaticResource number-style}" />
</FormattedString.Spans>
</FormattedString>
</Label.FormattedText>
</Label>
Bindable spans make for much simpler FormattedText. This is not the first time this has been requested.
https://xamarin.uservoice.com/forums/258559-xamarin-forms-suggestions/suggestions/6256703-extend-span-with-bindable-text-and-tapgesture
https://xamarin.uservoice.com/forums/258559-xamarin-forms-suggestions/suggestions/6622199-unseal-span-or-make-it-bindable
Also nice to have the ability to nicely format labels as follows.
Migrated from Evlolution
Bindable span should not present any major backwards compatibility issues at first blush. Changing the base class of Span on its own should not provide any breaks provided the same interfaces remain properly implemented.
XAML components should begin working automatically once the base class is updated.
any update on this ?
I'll pick this one up. Might pick up the commandable span regions as well, afterwards.
Binding Text all working
Styles I have working, but only if I inherit Span off VisualElement, which is incorrect because it then gives Span additional properties it shouldn't have.
What would be the best way to get Styles applied to a non VisualElement?
What about an IStylable
interface with a Style
property. Then VisualElement
can also implement it and styling throughout can utilize it... Might be too much change, but it shouldn't break anything.
The too much change is what I am concerned about. The Style in VisualElement sets a MergedStyle, which is a sealed class, inside the VisualElement class. So nothing else other than VisualElement can reach it at the moment. I'd have to pull that out. Messing around with the VisualElement is something I don't want to do, unless told to :)
Isn't it fairly unusual to be able to individually style spans in this way? Sure the whole label but each span? If you compare ios, I thought the attributable string can only be bolded etc as attributes on the string. I don't recall Android runs, so I thought they couldn't just be styled as a visual element either?
In other words I thought on the platforms string formatting sat outside of the normal style system
You can already set fonts etc to individual spans. The ability to add a Style, is only providing the ability to set these properties, via a Style. However with styles come triggers and reusability :)
@adamped Span
could inherit from Element
. Most of the boilerplate is done there. It should also implement IStyleSelectable
so it can be part of a CSS Selector and IStylable
so we can apply CSS properties to it.
while you're at it, it should implement ITextColor
(deprecate the ForegroundColor
property in favor of TextColor
)
I want to open dialer when user click on Request Number value. How is it possible?
@StephaneDelcroix - VisualElement has a style property that sets a property in a class scoped MergedStyle class. This class looks like it is doing the applying of the style. If I inherit directly from Element and implement the interfaces, no styles are applied.
To me it looks like the MergedStyle class is the key. Though i'm not pretending I know what it does at this stage. If I copy that out of the VisualElement. Then inherit Span from Element as suggested, but make the Style BindableProperty like this:
public Span()
{
_fontElement = new BindableSpan(this);
_mergedStyle = new MergedStyle(GetType(), this);
}
public readonly MergedStyle _mergedStyle;
public static readonly BindableProperty StyleProperty = BindableProperty.Create("Style", typeof(Style), typeof(Span), default(Style),
propertyChanged: (bindable, oldvalue, newvalue) => ((Span)bindable)._mergedStyle.Style = (Style)newvalue);
public Style Style
{
get { return (Style)GetValue(StyleProperty); }
set { SetValue(StyleProperty, value); }
}
Then styling all works. Can I pull the MergedStyle out of VisualElement, so it can be used by both Span and VisualElement?
@adamped yes, that looks fine. MergedStyle is indeed responsible for applying normal Styles, whereas CSS styles are applied through Element
@StephaneDelcroix - I have my PR ready for a pre-review. https://github.com/XamarinFormsCommunity/Xamarin.Forms/pull/4
Quick question: Do we need to squash our commits anymore, because now GitHub has a nice convenient Squash and Commit button.
@adamped your commits are fine as-is
This is great. I have been looking for this. How do you go about getting an update on your computer when this feature is completed?
When is this feature going to be released?
Looking forward to this. Any ETA for it?
So the pull request at XamarinFormsCommunity was done on Feb 9th, 2018. However, there's not a pull request here on the main Xamain.Forms project. Am I missing something in the process loop?
@DamianSuess commented on Apr 8, 2018, 4:21 PM GMT+2:
So the pull request at XamarinFormsCommunity was done on Feb 9th, 2018. However, there's not a pull request here on the main Xamain.Forms project. Am I missing something in the process loop?
Most helpful comment
Binding Text all working
Styles I have working, but only if I inherit Span off VisualElement, which is incorrect because it then gives Span additional properties it shouldn't have.
What would be the best way to get Styles applied to a non VisualElement?