7

I am having some issues inheriting from an implicit style defined in an Application ResourceDictionary. I have tried a couple of different approaches, but each has been unsuccessful in one form or another.

Attempt 1: Inherit from implicit style

Application ResourceDictionary

<Style TargetType="Button">
    <Setter Property="BackgroundColor" Value="#1386F1" />
    <Setter Property="TextColor" Value="White" />
    <Setter Property="FontAttributes" Value="Bold" />
    <Setter Property="HeightRequest">
      <OnPlatform x:TypeArguments="x:Double" iOS="30" Android="50" />
    </Setter>
    <Style.Triggers>
      <Trigger TargetType="Button" Property="IsEnabled" Value="False">
        <Setter Property="BackgroundColor">
          <OnPlatform x:TypeArguments="Color" iOS="#E8E8E8" />
        </Setter>
      </Trigger>
    </Style.Triggers>
</Style>

Page ResourceDictionary

<Style x:Key="LoginButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
    <Setter Property="BackgroundColor" Value="#024886" />
    <Setter Property="Margin">
      <OnPlatform x:TypeArguments="Thickness" iOS="0,5" />
    </Setter>
</Style>

Page Control

<Button Style="{StaticResource LoginButtonStyle}" />

Result

Throws exception "StaticResource not found for key {x:Type Button}". This is how I remember doing it in WPF, but I'm assuming this isn't supported in Xamarin XAML.

Attempt 2: Inherit from common explicit style

Application ResourceDictionary

<Style x:Key="DefaultButtonStyle" TargetType="Button">
    <!-- Same as Attempt 1 -->
</Style>
<!-- This implicit style causes issues with the inheritence of the Trigger in the above explicit style. When it's commented out, everything works fine. -->
<Style TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}" />

Page ResourceDictionary

<Style x:Key="LoginButtonStyle" TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}">
    <!-- Same as Attempt 1 -->
</Style>

Page Control

<!-- Same as Attempt 1 -->

Result

Everything works except for the Trigger. However, when I remove the implicit style the Trigger magically starts working again. I'd rather not have to specify the explicit style on every Button, though. I believe this is just a bug, but I wanted to make sure before I take the time to prepare a bug report.

Any ideas?

Question in Xamarin Forums

Taylor Buchanan
  • 4,155
  • 1
  • 28
  • 40
  • Hmm on android the trigger is working. Can't verify it on iOS right now. As a workaround (before you declare the trigger on each button), you could try to use a behavior. https://developer.xamarin.com/guides/xamarin-forms/behaviors/creating/ – Sven-Michael Stübe Aug 30 '16 at 19:09
  • The default background of a disabled button on Android is already the color I have specified in the trigger for iOS (#E8E8E8), so I'm not sure it's working there either. Since I am applying the trigger to iOS only, I have not tested if it works on Android. – Taylor Buchanan Aug 30 '16 at 19:21
  • I changed it to magenta and its working, too :) – Sven-Michael Stübe Aug 30 '16 at 19:24
  • And if you read the source code, you see that it is implemented. So maybe it is a bug. https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Core/Style.cs#L36 – Sven-Michael Stübe Aug 30 '16 at 19:26
  • Attempt 3: did you try defining trigger action in code? – nishantvodoo Aug 31 '16 at 12:44
  • @nishantvodoo No, I didn't. I am asking for the suggested method of defining the inheritance in XAML because that is what I prefer. – Taylor Buchanan Aug 31 '16 at 13:24
  • Just in case you decide using trigger in code. https://blog.xamarin.com/triggers-in-xamarin-forms/ (look Define the TriggerAction in code) It is actually as simple and as manageable as in XAML – nishantvodoo Aug 31 '16 at 13:31

1 Answers1

4

First of all, thanks for the nice summary!

In my opinion this is a bug, which can be prevented with a little trick:

<!-- Base Style -->
<Style x:Key="BaseButtonStyle" TargetType="Button">
    <!-- Define base button style... -->
</Style>

<!-- Implicit Style -->
<Style TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}"></Style>

<!-- Inherited Style -->
<Style x:Key="InheritedButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
    <!-- Extend base button style... -->
</Style>

Basically, the idea is to create a common explicit base style, which gets inherited by an implicit style afterwards. Therefore, all buttons are automatically applying the BaseButtonStyle, which is additionally extensible.

Attention: The implicit style has to be created after defining the base style.

EDIT: Apparently this is the same solution as #2 already provided before. So, the Trigger issue is not fixed, which seems to be a bug.

droide_91
  • 197
  • 2
  • 6
  • 1
    Thanks for the answer, but could you please specify to which bug you are referring? You have listed the same code as I listed in Attempt #2, so I fail to see how the `Trigger` bug I referred to would be prevented with what you have provided. – Taylor Buchanan Sep 07 '16 at 15:23
  • Oh, thanks for the clarification. Sorry, I oversaw that my solution is exactly the same as yours, because I mainly focused on the main question. As I am solely relying on data binding, I have not realized that triggers are not working. – droide_91 Sep 08 '16 at 08:51