XAML global style with gradient as background - xaml

You can set a gradient background inside the xaml for a page like this
<Button.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="White" Offset="0.6" />
<GradientStop Color="Blue" Offset="1.0" />
</LinearGradientBrush>
</Button.Background>
but when I search for the format to use when doing this in a global style like
<ResourceDictionary>
<Style TargetType="Button">
<Setter Property="BorderColor" Value="Lime" />
<Setter Property="BorderRadius" Value="10" />
......
I find nothing usable. It seems that is might not even be doable? Most links even seem to think there is no direct support for gradients without plugins, so perhaps it is a new addition to xamarin forms?
I specifically want to do this for buttons and contentpages, but I suspect the format will be the same for both - if it is supported at all.

You can try with the following:
<ResourceDictionary>
<Style TargetType="Button">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="White" Offset="0.6"/>
<GradientStop Color="Blue" Offset="1.0"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Keep in mind that currently Xamarin.forms is having an issue with global implicit style
Documentation: styles-and-templates

Related

XAML - Static resource not set

I have 2 styles in static resources. First ( with name LabelFont SetterProperty="FontSize")
<OnIdiom x:TypeArguments:"x:Double" Phone="15", Tablet "30"/>.
Second is for setting Margin with OnPlatform and is BasedOn="LabelFont" with name MarginLabel and SetterProperty="Margin":
<OnPlatform x:TypeArguments="x:Double">
<On Platform="Android" Value="20,0,0,0" />
</OnPlatform>
(Sorry I dont have whole code now, I can post later if its necessary...)
When I define a Label, where I use Style="{StaticResources MarginLabel}" the font is set, but not Margin. No error.
Can anybody help me where is the problem? Thank you.
Instead of creating two styles,you could combine them in one:
<Style x:Key="MarginLabel" TargetType="Label">
<Setter Property="FontSize">
<Setter.Value>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>15</OnIdiom.Phone>
<OnIdiom.Tablet>30</OnIdiom.Tablet>
</OnIdiom>
</Setter.Value>
</Setter>
<Setter Property="Margin">
<Setter.Value>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="Android" Value="20,0,0,0" />
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
then use like:
<Label Text="Hello" Style="{StaticResource MarginLabel}"></Label>

Xamarin.Forms setting specific style for platform

I'm trying to style my UWP application with some specific styles, while on other platforms it should remain default.
This is my project layout:
I tried the following things:
In Clients.Shared creating a style as following:
<Style x:Key="SomeStyle" TargetType="Button" />
And adding the same Style key in the Clients.Themes.UWP so it could hopefully override it, but no luck.
Then I tried Having a Dummy Style and using the onPlatform but that didn't work either, but I still think this is the way to go. I had the following code:
<Style x:Key="DummyStyle" TargetType="Button">
<Setter Property="Style">
<Setter.Value>
<OnPlatform x:Key="ButtonStyle" x:TypeArguments="Style">
<On Platform="UWP" Value="{StaticResource SomeStyle}"></On>
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
I tried messing around with merged ResourceDictionary.MergedDictionaries but there I couldn't include the xaml
Anybody have any clue?
Try this:
<OnPlatform x:TypeArguments="Color" Android="Green" iOS="White" WinPhone="White"
x:Key="PrimaryColor" />
<Style x:Key="ButtonColor" TargetType="Button">
<Setter Property="BackgroundColor" Value="{StaticResource PrimaryColor}" />
</Style>
<Button Text="Hello" HorizontalOptions="StartAndExpand"
Grid.Row="2" Grid.ColumnSpan="2" Style="{StaticResource ButtonColor}" />
In this example, I am defining a style for a Button called ButtonColor. This Button will use a BackgroundColor of white for all platforms except Android where it will be Green.
I find this is the most common use for this tag with regard to styling; if you are working with fonts, be sure to run on simulator and actual devices to get the font that you want.
This syntax works for me:
<Style x:Key="zoneLabelStyle" TargetType="Label">
<Setter Property="HeightRequest" Value="18" />
<Setter Property="Margin">
<OnPlatform x:TypeArguments="Thickness">
<On Platform="Android" Value="0, -3, 0, 0" />
</OnPlatform>
</Setter>
</Style>
Why do not use
<Button.Style>
<OnPlatform x:TypeArguments="x:Style">
<OnPlatform.iOS>...</OnPlatform.iOS>
<OnPlatform.Android>...</OnPlatform.Android>
<OnPlatform.WinPhone>...</OnPlatform.WinPhone>
</OnPlatform>
</Button.Style>
Hope it will help.

How to debug VisualStateManager in runtime

There are very helpful tools out there to debug WPF applications in run-time like Snoop, WPF Inspector and Xaml Spy which allow you to sneak peek into running application and monitor property values, DataContext changes, routing events and even triggers switching.
But what I did not managed to find in any of them is the way how to monitor VisualStateManager (VSM) transitions between states on particular selected control in run-time.
Is there any tool that could help with figuring out why a control doesn't go into the particular expected state (considering absence of source code for this application/library)?
Update: The question is mostly about debugging compiled code, when you have no access to the source. For cases when you have access to source code here is pretty good explanation of one of the ways to go.
There are some reasons why a control does not transect its states.
There might be more than one VisualStateGroup and its has been named as something.
Calling a visual state before a control is loaded.
VisualState will be applied only after the control's OnApplyTemplate call.
if there are any syntax error.
How ever the Visual states are not able to tract with something but it can be debugged with the return value of GoToState method.
Hope this would helpful..
I has this issue because I added a "<ControlTemplate.Triggers>" section, so I had both "Style.Triggers" and "ControlTemplate.Triggers", it worked until I click on a column header, which generated the error "ExceptionObject {"La propriété '[Unknown]' ne pointe pas vers un DependencyObject du chemin '(0).(1)[1].(2)'."} object {System.InvalidOperationException}"
<Style x:Key="GridViewColumnHeaderNoResize" TargetType="GridViewColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="{DynamicResource SolidColorBrushW1}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Grid MinHeight="35">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="HeaderBorder">
<EasingColorKeyFrame KeyTime="0" Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed" />
<VisualState x:Name="Disabled" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="HeaderBorder" BorderThickness="0,1,0,1" Padding="2,0,2,0">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}" Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ColorN3}" Offset="0.0" />
<GradientStop Color="{DynamicResource ColorN3}" Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter x:Name="HeaderContent"
Margin="0,0,0,1"
RecognizesAccessKey="True"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Thumb x:Name="PART_HeaderGripper" HorizontalAlignment="Right" Margin="0,0,-9,0"
Style="{StaticResource GridViewColumnHeaderGripper}" IsEnabled="False" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{DynamicResource SolidColorBrushN4}" TargetName="HeaderBorder" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Role" Value="Floating">
<Setter Property="Opacity" Value="0" /> <!-- 0.7 -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Canvas Name="PART_FloatingHeaderCanvas">
<Rectangle Fill="#60000000"
Width="{TemplateBinding ActualWidth}"
Height="{TemplateBinding ActualHeight}" />
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Role" Value="Padding">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<Border Name="HeaderBorder" BorderThickness="0,1,0,1">
<Border.Background>
<SolidColorBrush Color="{DynamicResource ControlLightColor}" />
</Border.Background>
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}" Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{DynamicResource SolidColorBrushN4}" />
</Trigger>
</Style.Triggers>
</Style>

Attach system colors to LinearGradientBrush

In my application I'd like to create a fading line that has GradientStops with system colors, I'm trying to do it like this:
<UserControl.Resources>
<Style x:Key="Divider" TargetType="Rectangle">
<Setter Property="Height" Value="2" />
<Setter Property="Fill">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="{StaticResource PhoneChromeBrush}" Offset="0.0" />
<GradientStop Color="{StaticResource PhoneInverseBackgroundBrush}" Offset="1.0" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
But when I try to compile project I get the following error:
A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in System.Windows.ni.dll
An exception of type 'System.Windows.Markup.XamlParseException' occurred in System.Windows.ni.dll but was not handled in user code
What should I do to fix this?
GradientStop.Color expects a color, not a brush. Use PhoneChromeColor and PhoneInverseBackgroundColor instead:
<UserControl.Resources>
<Style x:Key="Divider" TargetType="Rectangle">
<Setter Property="Height" Value="2" />
<Setter Property="Fill">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="{StaticResource PhoneChromeColor}" Offset="0.0" />
<GradientStop Color="{StaticResource PhoneInverseBackgroundColor}" Offset="1.0" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
I am not certain but it appears you may be setting a static color as a brush. It is hard to tell since you never posted the code to your static resource for 'PhoneChromeBrush' or 'PhoneInverseBackgroundBrush'. But you are setting gradient stops with these and if they are gradients themselves that may break your code. Usually you reserve 'brush' for a gradient so I was not certain:
could you not do something like:
<UserControl.Resources>
<LinearGradientBrush x:Key="MoneyBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#3A883A" Offset="1" />
<GradientStop Color="#FFFFFF" Offset="0" />
<GradientStop Color="#FF53AA75" Offset="0.50" />
<GradientStop Color="#073307" Offset="0.95" />
</LinearGradientBrush>
<Style x:Key="Divider" TargetType="Rectangle">
<Setter Property="Height" Value="2" />
<Setter Property="Fill" Value="{StaticResource MoneyBrush}"/>
</Style>
</UserControl.Resources>

Styles from a ResourceDictionary is preventing all other functionality

UPDATE: I moved the TextBox's style to the phone:PhoneApplicationPage.Resources tag and it behaves exactly the same way so it turns out that is not the fact the I am using a ResourceDictionary what is causing the problem but that there is something wrong with the way I am defining the style.
I just started playing around with ResourceDictionaries and I really like them but when I tried to use them on my application everything stopped working.
First the following TextBox:
<TextBox Grid.Column="1"
Grid.Row="0"
x:Name="Value"
InputScope="Number"
TextAlignment="Right"
TextChanged="OnValueTextChanged">
<TextBox.Style>
<StaticResource ResourceKey="InputTextBox" />
</TextBox.Style>
</TextBox>
Update: I have updated the ResourceDictionary per XAMeLi's answer and now I see the borders but it would seem as the TextBox does not have any background but, when I click on it nothing happens as if the TextBox is not even there. Then by pure luck I noticed that if I click on the bottom border the numeric keyboard would pop up as if the TextBox is too small or hiding below the border element. I tried modifying the TextBox height to no avail. This is driving me crazy.
Then the ListPickers are even worse:
<toolkit:ListPicker
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="1"
x:Name="CategoriesPicker"
HeaderTemplate="{StaticResource ListPickerHeaderTemplate}"
FullModeItemTemplate="{StaticResource CategoriesPickerTemplate}"
ExpansionMode="FullScreenOnly"
BorderThickness="0"
Padding="0"
Margin="0"
SelectionChanged="OnCategoriesPickerSelectionChanged">
<toolkit:ListPicker.Style>
<StaticResource ResourceKey="ListPickersStyle"/>
</toolkit:ListPicker.Style>
</toolkit:ListPicker>
When the Style is in it won't even bind the data I'm giving to it.
The file with the ResourceDictionary looks like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit">
<Style x:Name="InputTextBox" TargetType="TextBox">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="-12"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0 0" EndPoint="0 1">
<GradientStop Color="DarkGray" Offset="0"/>
<GradientStop Color="DarkGray" Offset=".3"/>
<GradientStop Color="LightSlateGray" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border
BorderThickness="2"
Margin="15"
CornerRadius="3">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0 0" EndPoint="0 1">
<GradientStop Offset="0" Color="DarkGray"></GradientStop>
<GradientStop Offset="0.3" Color="DarkGray"></GradientStop>
<GradientStop Offset="1" Color="LightSlateGray"></GradientStop>
</LinearGradientBrush>
</Border.BorderBrush>
<Border
BorderThickness="2"
CornerRadius="3">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="1 1" EndPoint="1 0">
<GradientStop Offset="1" Color="Gray"></GradientStop>
<GradientStop Offset="0.3" Color="DarkGray"></GradientStop>
<GradientStop Offset="0" Color="DarkGray"></GradientStop>
</LinearGradientBrush>
</Border.BorderBrush>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Name="ListPickersStyle" TargetType="toolkit:ListPicker">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ListPicker">
<Border
BorderThickness="2"
Padding="0"
Margin="10"
CornerRadius="3"
Background="DarkGray">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0 0" EndPoint="0 1">
<GradientStop Offset="0" Color="DarkGray"></GradientStop>
<GradientStop Offset="0.3" Color="DarkGray"></GradientStop>
<GradientStop Offset="1" Color="LightSlateGray"></GradientStop>
</LinearGradientBrush>
</Border.BorderBrush>
<Border BorderThickness="2"
CornerRadius="3">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="1 1" EndPoint="1 0">
<GradientStop Offset="1" Color="Gray"></GradientStop>
<GradientStop Offset="0.3" Color="DarkGray"></GradientStop>
<GradientStop Offset="0" Color="DarkGray"></GradientStop>
</LinearGradientBrush>
</Border.BorderBrush>
<toolkit:ListPicker
BorderThickness="0"
Padding="0"
Margin="0">
<toolkit:ListPicker.Background>
<LinearGradientBrush StartPoint="0 0" EndPoint="0 1">
<GradientStop Offset="0" Color="DarkGray"></GradientStop>
<GradientStop Offset="0.5" Color="DarkGray"></GradientStop>
<GradientStop Offset="1" Color="LightSlateGray"></GradientStop>
</LinearGradientBrush>
</toolkit:ListPicker.Background>
</toolkit:ListPicker>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Please, somebody explain to me what am I doing wrong.
Inside your ControlTemplates there are the controls them selves, i.e. control template for text box is holding a TextBox. This is not how control templates should be used. Use Blend or VS11 to extract the default style for each control (I'd recommend doing it in a new clean solution) and then change the visual appearance.
You should be able to reference the style just like any other property, e.g.:
<TextBox Style="{StaticResource InputTextBox}"/>
And try setting your Style first, then any settings you want to override, e.g.:
<TextBox Style="{StaticResource InputTextBox}" TextAlignment="Right" />
You should use x:Key instead of x:Name in ResourceDictionary:
x:Key and x:Name are not identical concepts. x:Key is used exclusively
in resource dictionaries. x:Name is used for all areas of XAML. A
FindName call using a key value will not retrieve a keyed resource.
However, Silverlight 5 can use an x:Name (or Name) attribute as the
substitute resource key for a resource item if no x:Key exists on the
item.
and as soon as Windows Phone is far from Silverlight 5, you can not use x:Name in the dictionary.