Eduardo Rosas' Blog

Learn Azure, Xamarin, WPF, and more!

How to design efficiently on Xamarin Forms - Explicit Styles

Photo 2-28-18, 1 01 21 PM.jpg

Explicit Styles

Designing efficiently on Xamarin Forms

In the previous post, I talked about the use of implicit styles in XAML as a way to become much more efficient when defining the layouts for our Xamarin Forms applications, since it allows for code reuse to be implemented when defining the overall value of certain properties that would be implemented on all of the elements of a certain type.

You can also keep taking a look at this repository to find step by step what was done in the previous post (by switching branches) and what is done in this post.

Why we need explicit styles

2018-02-27 15_26_03-XamlStyles - Microsoft Visual Studio.png

Like I mentioned in the previous post, using only implicit styles raises an issue: all the elements look the same. And while this may be a good thing in many applications, in the case of a calculator app we may need to set a certain style to some buttons, and another style to some other buttons. Let's face it, our calculator so far looks terrible with all the orange buttons.

During this post then, we will create other styles, three to be more precise, so we have a calculator that manages to distinct some buttons from others. Creating explicit styles requires the same steps needed to create implicit styles, there will only be one difference in the definition, but the main difference will be in its usage.

For those of you who are familiar with CSS, this will be very familiar, you may already know what steps are required and are only here to double check a couple of things, what we need is to set an identifier to the styles, and later point to the specific style from the elements.

For those of you who have used XAML before, maybe on Windows or WPF apps, you will notice a couple of things that are different, maybe you are here because your styling is not working the same way as it works with other platforms, but the basics here are the same.

So let's jump right in, now that this column is filled with text enough that the image to the left doesn't look alone.

 

Defining the identifier to the Style

This is the crucial difference between an implicit style and an explicit style. As soon as we set an identifier to a style, it becomes mandatory that you need to establish the styling explicitly, whilst if no style for a particular type has an identifier, the implicit style will be used. Taking the example that we have been working with, I can define a new style inside the Resources for my ContentPage (and inside the ResourceDictionary), that is identical to the implicit style, only this one is setting the BackgroundColor to be DodgerBlue, and that of course, this new one is setting its identifier through 'x:Key'.

<Style TargetType="Button" x:Key="numberButton">
    <Setter Property="FontSize" Value="30"/>
    <Setter Property="BackgroundColor" Value="DodgerBlue"/>
</Style>

And the effects of creating this style are......none. Of course, the implicit style is still being set in here, we have to explicitly define which buttons will be using this new style before seeing it applied.

Explicitly setting a style

Since the implicit style is still the one being set to all the buttons of our calculator, we will need to explicitly set this new 'numberButton' style as the style for the number buttons. And to do that, we will use a XAML syntax that will allow us to access the resources defined inside the ResourceDictionary. In all of the buttons that require it then, I will access the Style property and set it to point to this new resource.

<Button Grid.Row="2"
        Text="7"
        Style="{StaticResource numberButton}"/>
2018-02-28 13_36_32-XamlStyles - Microsoft Visual Studio.png

Here I have applied it to the seven button, immediately changing its style to this new one, very similar to the previous one, but no using a different BackgroundColor.

This is everything needed to implement explicit styles, now by accessing the StaticResources for the ContentPage, we can point to a style that is defined inside those resources so it can be applied. Of course, I can do the exact same thing with the other buttons that require this style, in my case, I will set this to the eight, nine, four, five, six, one, two, three, zero and decimal point buttons.

Now you may think that this is enough for you to go ahead and be as productive and efficient as possible when defining your user interfaces, you may now think that you can go ahead and define a couple more styles by copying the numberButton and simply changing the background color a bit.

While in this example it wouldn't be terrible if you did that (well, I don't think there is a scenario where it would be 'terrible'), it is still not the most efficient way. If two styles are similar, we can base one style on another one, removing the need to reset some setters, so we only need to write those setters that are absolutely necessary. Again, in this tiny example the impact may not be huge, but if you had a ton of setters, the impact would be more noticeable.

Basing styles on other styles

2018-02-28 13_45_25-XamlStyles - Microsoft Visual Studio.png

My calculator now looks a bit better, by setting an explicit style to the number buttons, but I may still want to create a couple more styles, one for the AC, +/-, and % buttons and another one for the operators.

This style would be very similar to the numberButton style: it will be setting the same FontSize, but with a different background.

I could of course simply create another style by copying the other style, change its Key and change its BackgroundColor, but this poses a small issue.

If we do that, we would be creating two identical setters in different parts of our code, so if we ever need to change it, we need to go to each part of the code and modify it. Again, having only two properties being set, in only 3 styles is not a big deal, but if our styles were much more complex, it wouldn't be ideal to have to change this property over and over.

By basing one style on another style we solve this issue. So instead of defining this new style like this:

<Style TargetType="Button" x:Key="operatorButton">
    <Setter Property="FontSize" Value="30"/>
    <Setter Property="BackgroundColor" Value="Green"/>
</Style>

We could base it on the numberButton style. Because notice it is using the same value for the FontSize property. So basing this style on another, will make this new one 'inherit' the setters of the other one:

<Style TargetType="Button" x:Key="operatorButton" BasedOn="{StaticResource numberButton}">
    <Setter Property="BackgroundColor" Value="Green"/>
</Style>
2018-02-28 14_05_27-XamlStyles - Microsoft Visual Studio.png

Notice that I'm pointing to the style in the same way here when setting the BasedOn value than when I set the Style value on a button, and that now, adding the FontSize setter is not necessary, unless I want to change it to be different than 30.

So after setting this new style as the style for the operator buttons, and creating a new style that I can apply to the rest of the buttons (which also includes a setter for the TextColor). I can come up with the result to the left.

I also did change the colors, I wasn't liking the result, but thanks to styles, I only needed to change it once, from the styles, for it to be applied to all the corresponding buttons.

This easy it is to use explicit styles, now if I needed to change the font size for all 19 buttons, I only need to do so inside the numberButton style. This one will directly impact the 11 buttons that point to it directly and then will inherit that value to the other two styles, effectively changing the font size to all 19 values.

And suddenly instead of having to set the font size 19 times, and the background color another 19 times, and the text color 3 times, you only set the font size and text color once, and the background color trice.

You could say you were 8 times more efficient than if you wouldn't have used styles.


This topic, along with many many others, is covered in greater depth in my 25-hour long "The Complete Xamarin Developer Course: iOS and Android" course, which you can practically steal from me by