Xamarin.forms: StyleSheets - Updating StyleClass at runtime has no effect

Created on 11 May 2018  路  8Comments  路  Source: xamarin/Xamarin.Forms

Description

It doesn't appear as though styles on an element be changed at runtime. They are applied as expected on initial load but I seem unable to dynamically change them at runtime based on some event. For example, in a page code-behind this scenario:

void ButtonClick() { myPage.MyCoolLabel.StyleClass = new List<string> { "someNewStyle" }; }

This has no effect and does not update MyCoolLabel with new styling defined in someNewStyle.

Steps to Reproduce

  1. Load a stylesheet on the page, I happen to be using code-behind in page constructor:
    Resources.Add(StyleSheet.FromAssemblyResource( typeof(ContentPageBase).GetTypeInfo().Assembly, "MyCoolProject.Assets.global.css"));
  2. Styles from global.css are applied as expected on initial load.
  3. Try and change StyleClass at runtime:
    void ButtonClick() { myPage.MyCoolLabel.StyleClass = new List<string> { "someNewStyle" }; }

    Expect to see styling change on the element but this is not the case - it does not update with styles from someNewStyle.

Is this behavior supported with StyleSheets/StyleClass?

Thanks,
Mark

  • Version with issue: Xamarin.Forms 3.0.0.446417

    • IDE: Visual Studio 2017 v15.7.1

    • Platform Target Frameworks:

    • Android: 8.1

    • Android Support Library Version: Xamarin.Android.Support.v4

    • Affected Devices: Samsung S6

CSS 4 mobcat bug

Most helpful comment

Would be great if StyleClass could also be used as BindableProperty.

All 8 comments

Would be great if StyleClass could also be used as BindableProperty.

@StephaneDelcroix has anyone picked this up yet? It's something I want for a project I am currently working on especially @Dresel idea of StyleClass being BindableProperty.

Happy to take a look if it's still not being worked on.

@CliffAgius not picked up yet, AFAIK. Not sure I'd like this to be a BindableProperty though...

Is there are reason why? This would really simplify building dynamic components (like it is in almost all common js view model binding frameworks).

I agree with @Dresel. In my project I have some elements its styles changing on view model props.
Currently I have to create multiple elements for every possible state and hide/show them with IsVisible.

e.g. a Button style depends on a prop IsOnline

grafik
grafik

<Button Text="connect" StyleClass="connect,online" IsVisible="{Binding IsOnline}">
<Button Text="offline" StyleClass="connect,offline" IsVisible="{Binding IsOnline, Converter={StaticResource InverseBoolConverter}}">

If StyleClass would be a BindableProperty I could write following:

<Button Text="connect" StyleClass="connect,online">
    <Button.Triggers>
        <DataTrigger TargetType="Button" Binding="{Binding IsOnline}" Value="False">
            <Setter Property="StyleClass" Value="connect,offline"/>
            <Setter Property="Text" Value="offline"/>
        </DataTrigger>
    </Button.Triggers>
</Button>

The example above is quite easy to handle but I have some more complex elements which getting styled differently by many different props.

I find this to be a major issue but k.

Hey guys, how r u doing?

Hope u don't missunderstand my point here but, what Done status means here?

The problem was really solved? I'm trying to do something similar to @mmacneil & @Dresel but i'm getting other error and it happens when I'm adding an element as a Child in a Stacklayout.

The exception received is: System.FormatException: 'Input string was not in a correct format.'

Here follows the code:

private static void AddPolicyLabels(StackLayout pnlWarningMessages, KeyValuePair<string, string> item) { bool showPolicy = ((UiPassword)ElementRegistry.getElement(item.Key)).IsPassword; if (showPolicy) { List<string> v = new List<string>(); v.Add("passwordStrengthPolicy"); Label lblPolicy = new Label() { Text = ValidationLabelBuilder.GetPasswordStrengthPolicy(((UiPassword)ElementRegistry.getElement(item.Key))), TextColor = Color.ForestGreen, }; lblPolicy.StyleClass = v; pnlWarningMessages.Children.Add(lblPolicy); } }
What I'm doing wrong? Should I open other issue or we can discuss/reopen this thread?

Hope have some return.

Cheers

Hey guys, how r u doing?

Hope u don't missunderstand my point here but, what Done status means here?

The problem was really solved? I'm trying to do something similar to @mmacneil & @Dresel but i'm getting other error and it happens when I'm adding an element as a Child in a Stacklayout.

The exception received is: System.FormatException: 'Input string was not in a correct format.'

Here follows the code:

private static void AddPolicyLabels(StackLayout pnlWarningMessages, KeyValuePair<string, string> item) { bool showPolicy = ((UiPassword)ElementRegistry.getElement(item.Key)).IsPassword; if (showPolicy) { List<string> v = new List<string>(); v.Add("passwordStrengthPolicy"); Label lblPolicy = new Label() { Text = ValidationLabelBuilder.GetPasswordStrengthPolicy(((UiPassword)ElementRegistry.getElement(item.Key))), TextColor = Color.ForestGreen, }; lblPolicy.StyleClass = v; pnlWarningMessages.Children.Add(lblPolicy); } }
What I'm doing wrong? Should I open other issue or we can discuss/reopen this thread?

Hope have some return.

Cheers

@leopoldovettor check the Xamarin.Forms version.

Cheers

Was this page helpful?
0 / 5 - 0 ratings