Xamarin.forms: Xamarin Forms - Style Trigger using DynamicResource values are broken

Created on 5 Aug 2019  路  5Comments  路  Source: xamarin/Xamarin.Forms

_This issue has been moved from a ticket on Developer Community._


Xamarin Forms version 4.1.0.618606

Please refer to the attached sample project called StyleTriggerTest.zip.

Create the following button style which changes the BackgroundColor based on the IsEnabled property (note the use of DynamicResource values):

<Color x:Key="ColorEnabled">Green</Color>
    <Color x:Key="ColorDisabled">Red</Color>

    <Style x:Key="ButtonStyleBroken" TargetType="Button">
      <Style.Triggers>
        <Trigger TargetType="Button" Property="IsEnabled" Value="True">
          <Setter Property="BackgroundColor" Value="{DynamicResource ColorEnabled}" />
        </Trigger>
        <Trigger TargetType="Button" Property="IsEnabled" Value="False">
          <Setter Property="BackgroundColor" Value="{DynamicResource ColorDisabled}" />
        </Trigger>
      </Style.Triggers>
    </Style>

Create the following View:

<StackLayout>
    <Entry
      Text="{Binding Text}"
    />

    <Button
      Style="{StaticResource ButtonStyleBroken}"
      IsEnabled="{Binding IsButtonEnabled}"
    />
  </StackLayout>

And ViewModel:

string _text;
    public string Text
    {
      get => _text;
      set
      {
        if (SetObservableProperty(ref _text, value))
          OnPropertyChanged(nameof(IsButtonEnabled));
      }
    }

    public bool IsButtonEnabled => !string.IsNullOrWhiteSpace(Text);
  1. When the page first loads, the button's BackgroundColor is red (correct).
  2. However, when text is entered into the entry, the button's BackgroundColor changes to gray (incorrect, should be green).
  3. Deleting the text in the entry changes the button's BackgroundColor back to red (correct).
  4. Now, entering or deleting text in the entry keeps the button's BackgroundColor red (incorrect, should be red if there is no text in the entry, and green if there is).

When DynamicResource is changed to StaticResource in the Style, everything works as expected. However, I need to use DynamicResource so that I can change themes at runtime.


Original Comments

Visual Studio Feedback System on 8/1/2019, 00:55 AM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.


Original Solutions

(no solutions)

style 3 feedback-ticket bug

Most helpful comment

Herewith the reproduction project as requested.

StyleTriggerTest.zip

All 5 comments

Herewith the reproduction project as requested.

StyleTriggerTest.zip

On both Android and iOS it seems that the color turns to the default color for that platform. Likely a problem in core.

I believe this to be highly related, but if I should file as separate bug please lmk.

Using latest version of Xamarin Forms (and corresponding Visual Material package) on latest version of VS2019, on iOS Simulator running iPhone 11 iOS 13 and physical device iPhone X iOS 12.4.1, a DataTrigger that applies a style changing the color, even if it's a StaticResource or just a plain old Color (as in the example below), does not actually trigger the color change (but all other properties in the Style get applied as expected, it is just the color that doesn't). Upon leaving and coming back to the view, the color is applied by the DataTrigger right away as expected.

        <Style x:Key="GimmeButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="Text" Value="Gimme!" />
            <Setter Property="IsEnabled" Value="True" />
            <Setter Property="HorizontalOptions" Value="EndAndExpand" />
            <Setter Property="VerticalOptions" Value="Center" />
        </Style>

        <Style
            x:Key="PurchasedButtonStyle"
            BasedOn="{StaticResource GimmeButtonStyle}"
            TargetType="{x:Type Button}">
            <Setter Property="Text" Value="Bought" />
            <Setter Property="BackgroundColor" Value="Green" />
            <Setter Property="IsEnabled" Value="False" />
        </Style>

        <Frame>
            <StackLayout Style="{StaticResource SettingStackStyle}">
                <Label Style="{StaticResource GoodieDescriptionStyle}" Text="Disable advertisements" />
                <Button
                    Command="{Binding BuyGoodieCommand}"
                    CommandParameter="{x:Static models:InAppPurchaseType.NoAds}"
                    Style="{StaticResource GimmeButtonStyle}">
                    <Button.Triggers>
                        <DataTrigger
                            Binding="{Binding DisabledAds}"
                            TargetType="{x:Type Button}"
                            Value="True">
                            <Setter Property="Style" Value="{StaticResource PurchasedButtonStyle}" />
                        </DataTrigger>
                    </Button.Triggers>
                </Button>
            </StackLayout>
        </Frame>

There has been a longstanding bug with buttons not updating their background color properly.
The workaround is adding a custom renderer for iOS:

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == nameof(Button.BackgroundColor) && Control != null && Element != null)
            {
                Control.BackgroundColor = Element.BackgroundColor.ToUIColor();
            }
        }

I run also into this issue. Cost me lots of time. Does not work on iOS, Android and UWP. Please fix it.
Nice if you could chane the Bug-Title to "StaticResource & DynamicResource". So its easier to find for others too.

Was this page helpful?
0 / 5 - 0 ratings