Xamarin Forms Styling using StyleClass vs Style attribute - xaml

We're building a Xamarin Forms app we've noticed we could style an element in 2 ways by creating styles in the App.xaml ResourceDictionary
Class and StyleClass option
In App.xaml we'll write
<Style Class="EntryStandard" TargetType="Entry">
<Setter Property="TextColor" Value="#575e62" />
<Setter Property="BackgroundColor" Value="#9facb3" />
<Setter Property="FontSize" Value="14" />
</Style>
Then this gets used in one of the contentpages like this
<Entry StyleClass="EntryStandard" Placeholder="Login Name" Text="{Binding EntryEmailAddress}" />
Key and Style option
This is what we write under App.xaml
<Style x:Key="ButtonMainMenu_Purple" TargetType="Button">
<Setter Property="BackgroundColor" Value="#5d4785" />
<Setter Property="FontSize" Value="14" />
<Setter Property="TextColor" Value="#FFFFFF" />
</Style>
And then we use the following in our contentpages
<Button Style="{StaticResource ButtonMainMenu_Purple}" Text="Friends" Command="{Binding OnFriendsButtonCommand}" />
Both work fine, I just wanted to know which one is better than the other and why?

Regular styles follow the standard, relatively inflexible WPF model. Style classes includes cascade semantics and are part of the new theme support. They are poorly documented, however, and still in beta.

Related

How to add a true corner radius to the menu flyout?

Now it looks like this.
I use MenuFlyoutPresenterStyle in MenuFlyout -
<MenuFlyout x:Name="MenuFlyout"
MenuFlyoutPresenterStyle="{ThemeResource MenuFlyoutAcrilickThemeResources}"
>
<MenuFlyoutItem Icon="Paste" Text="Вставить" Click="MenuFlyoutItemPaste_Click" />
<MenuFlyoutItem Icon="Copy" Text="Скопировать" Click="MenuFlyoutItemCopy_Click" />
</MenuFlyout>
</MenuFlyout>
Style code
<Style x:Key="MenuFlyoutAcrilickThemeResources" TargetType="MenuFlyoutPresenter">
<Setter Property="CornerRadius" Value="10" />
<Setter Property="Padding" Value="0,3" />
<Setter Property="Background" Value="{ThemeResource MenuFlyoutBackgroundAcrylicBrush}" />
</Style>
How to fix this?
Use IsDefaultShadowEnabled to false.
<Button Content="Options">
<Button.Flyout>
<MenuFlyout>
<MenuFlyout.MenuFlyoutPresenterStyle>
<Style TargetType="MenuFlyoutPresenter">
<Setter Property="CornerRadius" Value="20"/>
<Setter Property="IsDefaultShadowEnabled" Value="False"/>
</Style>
</MenuFlyout.MenuFlyoutPresenterStyle>
<MenuFlyoutItem Text="Reset"/>
<MenuFlyoutSeparator/>
<ToggleMenuFlyoutItem Text="Repeat" IsChecked="True"/>
<ToggleMenuFlyoutItem Text="Shuffle" IsChecked="True"/>
</MenuFlyout>
</Button.Flyout>
</Button>
You should add another Setter which affects the default shadow property, like this:
<Setter Property="IsDefaultShadowEnabled" Value="False" />
Also I recommend using a corner radius of 3, since that's what WinUI 3 uses.
You can add another Setter to modify the background property:
<Setter Property="Background" Value="Transparent" />
However, depending on your SDK verison, Microsoft recommends a different approach:
Starting in Windows 10, version 1607 (SDK 14393), generic.xaml includes resources that you can use to modify the colors of a control in different visual states without modifying the control template. In apps that target this software development kit (SDK) or later, modifying these resources is preferred to setting properties such as Background and Foreground. For more info, see the Light-weight styling section of the Styling controls article.

How is it suggested to inherit from an implicit style in Xamarin.Forms XAML?

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
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.

WinRT XAML Toolkit NumericUpDown Template

I am using WinRT XAML Toolkit in Windows Universal Application C#.
I want to change distance between plus(+) and minus(-) buttons and increase size of both buttons.
There are templates available for WPF but not for Universal app.
Here is image
Please advice me how can I achieve it?
The template is in the toolkit here.
You might be able to get what you want by changing these button styles to add the Margin:
<!-- DecrementButtonStyle -->
<Style
x:Key="DecrementButtonStyle"
BasedOn="{StaticResource NumericUpDownButtonStyle}"
TargetType="RepeatButton">
<Setter
Property="Content"
Value="➖" />
<Setter
Property="Margin"
Value="5" />
</Style>
<!-- IncrementButtonStyle -->
<Style
x:Key="IncrementButtonStyle"
BasedOn="{StaticResource NumericUpDownButtonStyle}"
TargetType="RepeatButton">
<Setter
Property="Content"
Value="➕" />
<Setter
Property="Margin"
Value="5" />
</Style>

Viewbox and border

I am writing a Store app with XAML and C#. I want to use Border and ViewBox. I got border styled, so I do not have to set properties that many times. I set BorderThickness to 2, and color to White, but this causes problems in my Viewbox.
Here it is in XAML:
<Viewbox Grid.Row="1" Stretch="Uniform">
<Grid Width="600" Height="600">
<Grid.Resources>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="White" />
<Setter Property="BorderThickness" Value="2" />
</Style>
<Style TargetType="Grid">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="150" />
</Style>
</Grid.Resources>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Grid>
<Border>
<Viewbox>
<TextBlock Text="T" />
</Viewbox>
</Border>
</Grid>
The result of this is:
The problem is the scaled border around the letter "T".
I do not want to remove above styling for Border in Grid.Resources. I found only one solution so far...
<Viewbox>
<Viewbox.Resources>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="White" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</Viewbox.Resources>
<TextBlock Text="T" />
... what would give correct result:
, but I do not want to put these lines after each ViewBoxes, because there will be many.
I also tried to make a component, what has this default "resource" of zero thick border, but that had bad scaling.
So my question is how to to remove that border?
You're right to use the zero value for BorderThickness. There just might be another element in the visual tree hierarchy that also holds a default value that causes this.
I can't test this right now, but I can recommend this tool to you:
http://blois.us/Snoop/
You can inspect the visual tree with this by dragging the crosshair above your running debug application. Every time I stumbled upon a problem like this I found it highly useful to see which controls really appear at runtime, because with xaml it can be really tough to know it all. Hope you can find it!

Inheritance in Silverlight 2 Styles

I want to build up styles in XAML, e.g.
<UserControl.Resources>
<Style x:Key="MyStyle" TargetType="TextBlock">
<Setter Property="Margin" Value="2,2,2,2" />
<Setter Property="Foreground" Value="DarkRed" />
</Style>
<Style x:Key="MyBoldStyle" TargetType="TextBlock">
<Setter Property="Style" Value="{StaticResource MyStyle}" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</UserControl.Resources>
But this does not work. (In Silverlight 2) How can I make one inherit from the other?
June 2010 Update: Style Inheritance is in Silverlight 3, use BasedOn="{StaticResource MyStyle}
Nevermind. I found the answer in MacDonald's Pro Silverlight 2 in C# 2008:
(source: apress.com)
"If you've used styles in WPF, you'll find
that Silverlight styles are
dramatically scaled back ... [for example, you can't]
create styles that inherit from other styles."
Too bad. Maybe in Silverlight 3.