Attach system colors to LinearGradientBrush - xaml

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>

Related

XAML global style with gradient as background

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

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>

How to use a template for TextBox of WPF 2010

I have a template written in xaml. Can you write how a template is turned on for TextBox?
<Grid.Resources>
<Storyboard x:Key="FlashErrorIcon">
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Hidden}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:03.2000000" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:01" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="Background" Value="Pink"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
</Style.Triggers>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True"
ToolTip="{Binding ElementName=controlWithError,Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<Ellipse DockPanel.Dock="Right"
ToolTip="{Binding ElementName=controlWithError,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Width="15" Height="15"
Margin="-25,0,0,0"
StrokeThickness="1" Fill="IndianRed" >
<Ellipse.Stroke>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FFFA0404" Offset="0"/>
<GradientStop Color="#FFC9C7C7" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Stroke>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource FlashErrorIcon}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<TextBlock DockPanel.Dock="Right"
ToolTip="{Binding ElementName=controlWithError,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"
Foreground="White"
FontSize="10"
Margin="-15,5,0,0" FontWeight="Bold">!
<TextBlock.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource FlashErrorIcon}"/>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder Name="controlWithError"/>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
I tried to include in TextBox different ways, but I didn't manage to do it. How to include this template?
<TextBox>?????????What should I write here???????????>
?????????What should I write here???????????
</TextBox>
How to turn on the template? Any help will be appreciated!
You forgot to add the key textBoxInError to your TextBox style:
<Grid.Resources>
...
<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
...
</Style>
...
</Grid.Resources>
Without that key the Style is handled as default style for TextBox. In that case you would not explicitly reference a Style in your TextBox declaration, and would have to remove the Style="{StaticResource textBoxInError}" part.
EDIT: If your Style is contained in a resource dictionary (like Grid.Resources in your XAML) and has a Key as shown above (textBoxInError), you would use that Style like this:
<Grid>
<Grid.Resources>
<Style x:Key="textBoxInError" TargetType="{x:Type TextBox}">
...
</Style>
...
</Grid.Resources>
...
<TextBox Style="{StaticResource textBoxInError}" ... />
</Grid>
You style has the following deceleration:
This means this style will be applied to all textboxs. Unless you set a different style yourself.
When you write this:
<TextBox Validation.ErrorTemplate="{StaticResource FlashErrorIcon}"
Style="{StaticResource textBoxInError}" TabIndex="1" Margin="147,145,168,131">
You're changing the default style (to the one named textboxInError ) ...
So just remove the Style attribute from the textbox.
Another Solution
If you want to give the style a specific name and not make it the default style, use:
<Style TargetType="{x:Type TextBox}" x:Key="textBoxInError" >
And then your original code will work correctly
e.g.
<TextBox Style="{StaticResource textBoxInError}" />

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.

How to link Property value to a Property of a Style in Blend 4?

I created a Style template in Blend 4 for a button, but I'm not sure how to link the Label's Content to the Button's Content property.
Here's the style XAML:
<Style x:Key="NavButton" TargetType="Button">
<Setter Property="Background" Value="#FF1F3B53"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled"/>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle Stroke="#FF0E1AD2" RadiusY="7" RadiusX="7" StrokeThickness="4">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.517,1.07" StartPoint="0.511,0.001">
<GradientStop Color="#FF1828AB" Offset="1"/>
<GradientStop Color="#FFFBDEDE"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Margin="15,6,11,15" RadiusY="7" RadiusX="7" Stroke="#FF0E11D2" StrokeThickness="0">
<Rectangle.Fill>
<SolidColorBrush Color="White" Opacity="0.3"/>
</Rectangle.Fill>
</Rectangle>
<sdk:Label Margin="8" RenderTransformOrigin="1.567,-0.25" HorizontalContentAlignment="Center" Content="Button"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You use template bindings to bind controls inside a control template to properties of the control that they're templating. For example:
<Label Content="{TemplateBinding Content}"/>