2
votes

I am trying to get a subclass of the Xamarin Forms "Label" class. In my subclass, among a lot of other changes, I want to have a different default value for some bindable properties (such as FontSize and FontAttributes). However, if I set these in the constructor, it seems that Style specifiers won't override these, presumably because the bindings are already noticing that they are using non-default values. Is there a way to specify in a subclass that you want to use different default values in a bindable property?

class MyCustomLabel : Label {
  public MyCustomLabel() {
    FontSize=20;
  }
}

<ResourceDictionary>
  <Style x:Key="Superbig" TargetType="MyCustomLabel">
    <Setter Property="FontSize" Value="3" />
  </Style>
</ResourceDictionary>

<MyCustomLabel Style="{StaticResource Superbig}" Text="Hi There!" />

Here, the Superbig style is not being applied because I am setting the new default value in the constructor. Therefore, I was hoping either (a) there was some other way to set a new default value, or (b) there was some other way to set a style so it overrode any value that was already set.

1
I don't think it will be possible. Static properties, as the bindable is, cannot be overriden. And the styles 'runs' before the constructor. What if you set the new default value only if its the 'default default'? (Sorry my bad English)Diego Rafael Souza
Your English is fine. Is there a way to know if the default has been changed? A simple comparison wouldn't work because someone might change it back to the original.johnnyb
I'm afraid the only way is by the OnPropertyChanged eventDiego Rafael Souza

1 Answers

2
votes

Unfortunately, BindableProperty doesn't seem to support OverrideMetadata like DependencyProperty does. Here's two way to achieve this.

1) Set a default Style for your MyCustomLabel object (XAML)

    <ResourceDictionary>
        <!--Default style-->
        <Style TargetType="local:MyCustomLabel">
            <Setter Property="FontSize" Value="10" />
        </Style>

        <!--Superbig style-->
        <Style x:Key="Superbig" TargetType="local:MyCustomLabel">
            <Setter Property="FontSize" Value="40" />
        </Style>
    </ResourceDictionary>

2) Create a new FontSize BindableProperty (C#)

public class MyCustomLabel : Label
{
    public MyCustomLabel()
    {
        base.SetBinding(Label.FontSizeProperty, new Binding(nameof(FontSize))
        {
            Source = this,
            Mode = BindingMode.OneWay
        });
    }

    //Don't forget the "new" keyword
    public new double FontSize
    {
        get { return (double)GetValue(FontSizeProperty); }
        set { SetValue(FontSizeProperty, value); }
    }

    //Don't forget the "new" keyword
    public static readonly new BindableProperty FontSizeProperty =
        BindableProperty.Create(nameof(FontSize), typeof(double), typeof(MyCustomLabel), 40.0);
}