I am having difficulties to wrap my head around using Shapes.Path geometry data as content for a button. The style concept is: content inflates when the mouse enters and deflates when leaving. This works all as intended except for customization. I seem to be unable to change the path data when using this style.
<PathGeometry x:Key="PauseGeo">
M13,16V8H15V16H13M9,16V8H11V16H9M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z
</PathGeometry>
<PathGeometry x:Key="PlayGeo">
M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M10,16.5L16,12L10,7.5V16.5Z
</PathGeometry>
<Style x:Key="ButtonInflateStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<Grid x:Name="ButtonGrid" RenderTransformOrigin="0.5,0.5" >
<Grid.RenderTransform>
<ScaleTransform/>
</Grid.RenderTransform>
<Path x:Name="PathButton" Data="{StaticResource PlayGeo}" Fill="White" Stretch="Uniform"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ButtonGrid"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)"
From="1"
To="1.1"
Duration="0:0:0.3" />
<DoubleAnimation
Storyboard.TargetName="ButtonGrid"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)"
From="1"
To="1.1"
Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ButtonGrid"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)"
From="1.1"
To="1"
Duration="0:0:0.3" />
<DoubleAnimation
Storyboard.TargetName="ButtonGrid"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)"
From="1.1"
To="1"
Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Grid.Opacity)" From="1" To="0" BeginTime="0:0:0" Duration="0:0:.125" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="PathButton" Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And use it like this
<Button Style="{StaticResource ButtonInflateStyle}" x:Name="buttonPausePlay" Grid.Column="2">
<Path Data="{StaticResource PauseGeo}"></Path>
</Button>
Button image remains the on as defined in style.
I prefer XAML only solutions but I assume a CustomControl is needed. Or is it? Could someone point me in the right direction, please?
The Path in the ControlTemplate could use the Button's Content for its Data:
<Path x:Name="PathButton"
Data="{TemplateBinding Content}"
Fill="White" Stretch="Uniform"/>
Then you would assign a Geometry to the Button's Content when you use it:
<Button Style="{StaticResource ButtonInflateStyle}"
Content="{StaticResource PauseGeo}" .../>
or
<Button Style="{StaticResource ButtonInflateStyle}">
<StaticResource ResourceKey="PauseGeo"/>
</Button>
Related
I have a reset button - the desired behaviour is to increase in size on mouseover and, once clicked, have a border around it.
The IsMouseOver trigger works, but I can't get the MouseUp event trigger to work (once pressed the button does not display a border).
I have tried the following:
1) Adding an event trigger to the control template triggers
2) Adding an event trigger to the style triggers
3) Adding an event trigger to the button triggers
Am I writing the event trigger incorrectly? I've added the code for the three attempts below - hoping I've just missed something obvious and is a quick fix. Thanks!
1 - Adding an event trigger to the control template triggers
<Button x:Name="ResetButton"
Margin="0,0,20,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding Path=DoClearCmd}"
ToolTip="Reset all search criteria.">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text=" Reset" />
<Image Width="16"
Height="16"
Margin="2,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center" Source="..\Resources\Delete_16x16.png" />
</StackPanel>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="dx:ThemeManager.ThemeName" Value="None" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="MinHeight" Value="25" />
<Setter Property="MinWidth" Value="25" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1" ScaleY="1" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseUp">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<ColorAnimation Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="Tomato" />
<DoubleAnimation Storyboard.TargetProperty="BorderThickness" To="2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1.05" />
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1.05" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1" />
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
2 - Adding an event trigger to the style triggers
<Button x:Name="ResetButton"
Margin="0,0,20,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding Path=DoClearCmd}"
ToolTip="Reset all search criteria.">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text=" Reset" />
<Image Width="16"
Height="16"
Margin="2,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="..\Resources\Delete_16x16.png" />
</StackPanel>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="dx:ThemeManager.ThemeName" Value="None" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="MinHeight" Value="25" />
<Setter Property="MinWidth" Value="25" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1" ScaleY="1" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1.05" />
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1.05" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1" />
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="MouseUp">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<ColorAnimation Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="Tomato" />
<DoubleAnimation Storyboard.TargetProperty="BorderThickness" To="2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
3 - Adding an event trigger to the button triggers
<Button x:Name="ResetButton"
Margin="0,0,20,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Command="{Binding Path=DoClearCmd}"
ToolTip="Reset all search criteria.">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text=" Reset" />
<Image Width="16"
Height="16"
Margin="2,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="..\Resources\Delete_16x16.png" />
</StackPanel>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="dx:ThemeManager.ThemeName" Value="None" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="MinHeight" Value="25" />
<Setter Property="MinWidth" Value="25" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1" ScaleY="1" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1.05" />
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1.05" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1" />
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.MouseUp">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<ColorAnimation Storyboard.TargetName="ResetButton" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="Tomato" />
<DoubleAnimation Storyboard.TargetName="ResetButton" Storyboard.TargetProperty="BorderThickness" To="2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
To animate Thickness, you have to use ThicknessAnimation
Button does not fire MouseLeftButtonUp routed event. Workaround is to use PreviewMouseLeftButtonUp event. Source
You have to bind your "Border" element properties BorderBrush and BorderThickness to your template.
For your first case:
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="dx:ThemeManager.ThemeName" Value="None" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="MinHeight" Value="25" />
<Setter Property="MinWidth" Value="25" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1" ScaleY="1" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseUp">
<BeginStoryboard>
<Storyboard Duration="0:0:2" AutoReverse="True" RepeatBehavior="Forever">
<ColorAnimation Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" To="Tomato" />
<ThicknessAnimation Storyboard.TargetProperty="BorderThickness" To="4" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1.05" />
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1.05" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1" />
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
NOTE that MouseUp is firing only for Right mouse button up
Hope, it helps
The reason why these methods don't work is because the MouseUp event is consumed by the button, and never gets to your handler. This can be demonstrated by a right click (which isn't consumed) instead of a left click, and your above code will work (I only tested the first sample).
To solve this you can use use the PreviewMouseUp event instead. This worked for me in your first sample.
Example Button Link
Can WPF do shape animation likes this button click's effect? I try to use double animation the width and cornerRadius but the effects is not quite good. I using the path animation to animate the progress circle but only the shape animation I really don know how to animate it. Anyone can help me or give some ideas?
This is my Code
<Path x:Name="path" Height="20" Width="20" Stroke="Gray" Stretch="Fill" Opacity="0.3"
StrokeThickness="2" Data="m35,2.5c17.955803,0 32.5,14.544199 32.5,32.5c0,17.955803 -14.544197,32.5 -32.5,32.5c-17.955803,0 -32.5,-14.544197 -32.5,-32.5c0,-17.955801 14.544197,-32.5 32.5,-32.5z"
StrokeDashOffset="204.243713378906">
<Path.StrokeDashArray>
<System:Double>204.243713378906</System:Double>
</Path.StrokeDashArray>
</Path>
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard Storyboard.TargetName="bdrTest">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="path"
Storyboard.TargetProperty="(Shape.StrokeDashOffset)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="204.243713378906"/>
<SplineDoubleKeyFrame KeyTime="00:00:5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
What you are calling Animations are not Animations. It is simply the Button.Background and Button.Foreground changing colour in response to mouse over events. To give a Button rounded corners, you just need to supply your own ControlTemplate for the Button:
<Button Content="Submit" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="30" BorderThickness="2" BorderBrush="#FF1ECD97"
TextElement.Foreground="#FF1ECD97" TextElement.FontSize="20"
TextElement.FontWeight="SemiBold" Padding="100,20">
<ContentPresenter />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
Now to add the mouse over effects, we just need to add a Trigger to the ControlTemplate to change the colour of the Button.Background and Button.Foreground when the UIElement.IsMouseOver property is True:
<Button Content="Submit" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" CornerRadius="30" Background="Transparent"
BorderThickness="2" BorderBrush="#FF1ECD97" TextElement.Foreground=
"#FF1ECD97" TextElement.FontSize="20" TextElement.FontWeight="SemiBold"
Padding="100,20">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background"
Value="#FF1ECD97" />
<Setter TargetName="Border" Property="TextElement.Foreground"
Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
The most difficult thing is animating the circular progress. If using codebehind, it's not such problematic. But I tried to use pure XAML. In codebehind we can calculate the Point of some ArcSegment from the corresponding angle and update the ArcSegment accordingly. But in XAML, we have to use some hacky work-around. I had to use 4 layers of borders to create this effect. Firstly I tried with just 2 layers but because changing the Background while animating it simply makes the animation not work expectedly.
I will concentrate mainly on the circular progress effect because this is the most challenging problem when solving with pure XAML. Basically you need some background Border having 2 halves with different colors making a full circle. The left half is grayed, the right half has active (progressed) color. This border is fixed:
You need another Border also with 2 different halves. Its left half is transparent and its right half has active/progressed color. This Border will be rotated (in fact its Background is rotated) in the second phase after the first phase is 180 degree rotated:
The next Border will be used in the first phase. This border also has 2 different halves. The left half is transparent and the right half is grayed:
So initially, these 3 Borders will make a full grayed circle (the left grayed half is of the first Border, the right grayed half is of the third):
In the first phase, the third border is 180 degree rotated. Its grayed half will gradually open the underneath active-color half of the second Border making the effect of progressing from 0 to 180 degree. After that the first phase has been finished. The third Border will be hidden, the second Border will be rotated. Now its active-color half (the right half) will gradually cover the grayed half of the first Border (on the left) and make the effect progressing from 180 to 360 (full of active color).
There are still other Border layers for the last effect of showing tickmark,... Here is the full code. It's fairly long and it's mainly used for reference, you may have to improve it much so that it can be used in your code. I just used simple animations (without easing):
<Button Background="Transparent" Content="Submit" FontSize="30" Foreground="#FF1ECD97" BorderBrush="#FF1ECD97">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Height" Value="80"/>
<Setter Property="Width" Value="280"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Button.Style>
<Button.Template>
<ControlTemplate TargetType="Button">
<ControlTemplate.Resources>
<DrawingBrush Stretch="Fill" x:Key="circle">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Geometry="M-25,-25 h50v50h-50v-50" Brush="Transparent">
</GeometryDrawing>
<GeometryDrawing Geometry="M0,-25 A25,25 0 0 1 0,25">
<GeometryDrawing.Pen>
<Pen Brush="{DynamicResource right}" Thickness="4"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M0,25 A25,25 0 0 1 0,-25">
<GeometryDrawing.Pen>
<Pen Brush="{DynamicResource left}" Thickness="4"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
<DrawingBrush.RelativeTransform>
<RotateTransform Angle="0" CenterX="0.5" CenterY="0.5"/>
</DrawingBrush.RelativeTransform>
</DrawingBrush>
<DrawingBrush x:Key="ok" Stretch="None">
<DrawingBrush.Drawing>
<GeometryDrawing Geometry="M0,20 L10,30 30,5">
<GeometryDrawing.Pen>
<Pen Brush="White" Thickness="5" EndLineCap="Round" StartLineCap="Round"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
<DrawingBrush.RelativeTransform>
<ScaleTransform CenterX="0.5" CenterY=".5" ScaleX="0" ScaleY="0"/>
</DrawingBrush.RelativeTransform>
</DrawingBrush>
</ControlTemplate.Resources>
<Grid>
<Grid.Effect>
<DropShadowEffect ShadowDepth="1"/>
</Grid.Effect>
<Border BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource TemplatedParent}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource TemplatedParent}}" CornerRadius="40"
Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}">
</Border>
<Border Opacity="0" Name="b1">
<Border.Resources>
<SolidColorBrush Color="#FF1ECD97" x:Key="right"/>
<SolidColorBrush Color="#ffdddddd" x:Key="left"/>
</Border.Resources>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{StaticResource circle}"/>
</Style>
</Border.Style>
</Border>
<Border Opacity="0" Name="b12">
<Border.Resources>
<SolidColorBrush Color="#FF1ECD97" x:Key="right"/>
<SolidColorBrush Color="Transparent" x:Key="left"/>
</Border.Resources>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{StaticResource circle}"/>
</Style>
</Border.Style>
</Border>
<Border Opacity="0" Name="b2">
<Border.Resources>
<SolidColorBrush Color="#ffdddddd" x:Key="right"/>
<SolidColorBrush Color="Transparent" x:Key="left"/>
</Border.Resources>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="{StaticResource circle}"/>
</Style>
</Border.Style>
</Border>
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Name="cp"/>
<Border Opacity="0" Name="b3_" Background="#FF1ECD97" CornerRadius="40"/>
<Border Opacity="0" Name="b3" Background="{StaticResource ok}"/>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard Name="bg">
<Storyboard Duration="0:0:6" FillBehavior="Stop">
<DoubleAnimation Storyboard.TargetProperty="Width" To="80" Duration="0:0:.2">
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="b1" Storyboard.TargetProperty="Opacity" BeginTime="0:0:.2" To="1" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="b2" Storyboard.TargetProperty="Opacity" BeginTime="0:0:.2" To="1" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="cp" Storyboard.TargetProperty="Opacity" To="0" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="b2" Storyboard.TargetProperty="Background.RelativeTransform.Angle" By="180" BeginTime="0:0:.2" Duration="0:0:2"/>
<DoubleAnimation Storyboard.TargetName="b12" Storyboard.TargetProperty="Opacity" BeginTime="0:0:2.2" To="1" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="b2" Storyboard.TargetProperty="Opacity" BeginTime="0:0:2.2" To="0" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="b12" Storyboard.TargetProperty="Background.RelativeTransform.Angle" By="180" Duration="0:0:2" BeginTime="0:0:2.2"/>
<!-- Reset -->
<DoubleAnimation Storyboard.TargetName="b1" Storyboard.TargetProperty="Opacity" BeginTime="0:0:4.2" To="0" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="b2" Storyboard.TargetProperty="Opacity" BeginTime="0:0:4.2" To="0" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="b12" Storyboard.TargetProperty="Opacity" BeginTime="0:0:4.2" To="0" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="b2" Storyboard.TargetProperty="Background.RelativeTransform.Angle" To="0" BeginTime="0:0:4.2" Duration="0:0:0"/>
<DoubleAnimation Storyboard.TargetName="b12" Storyboard.TargetProperty="Background.RelativeTransform.Angle" To="0" Duration="0:0:0" BeginTime="0:0:4.2"/>
<DoubleAnimation Storyboard.TargetProperty="Width" To="280" BeginTime="0:0:4.2" Duration="0:0:.2"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="b3" Storyboard.TargetProperty="Opacity" BeginTime="0:0:4.2" To="1" Duration="0:0:0"/>
<DoubleAnimation Storyboard.TargetName="b3_" Storyboard.TargetProperty="Opacity" BeginTime="0:0:4.2" To="1" Duration="0:0:.1"/>
<DoubleAnimation Storyboard.TargetName="b3" Storyboard.TargetProperty="Background.RelativeTransform.ScaleX" To="1" Duration="0:0:.2" BeginTime="0:0:4.2"/>
<DoubleAnimation Storyboard.TargetName="b3" Storyboard.TargetProperty="Background.RelativeTransform.ScaleY" To="1" Duration="0:0:.2" BeginTime="0:0:4.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition SourceName="b1" Property="Opacity" Value="0"/>
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="#FF1ECD97" Duration="0:0:.3">
</ColorAnimation>
<ColorAnimation Storyboard.TargetProperty="Foreground.Color" To="White" Duration="0:0:.3">
</ColorAnimation>
<ThicknessAnimation Storyboard.TargetProperty="BorderThickness" To="0" Duration="0:0:0">
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="Transparent" Duration="0:0:.3">
</ColorAnimation>
<ColorAnimation Storyboard.TargetProperty="Foreground.Color" To="#FF1ECD97" Duration="0:0:.3">
</ColorAnimation>
<ThicknessAnimation Storyboard.TargetProperty="BorderThickness" To="2" Duration="0:0:0">
</ThicknessAnimation>
</Storyboard>
</BeginStoryboard>
</MultiTrigger.ExitActions>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
I know you can wrap a Grid in a ScrollViewer, and the scrolling works automatically. However, I want to make my own scrollbars around the grid. So far, I managed to sync the scrollbar with the grid when I move around the grid. However, I couldn't find properties or methods of the Grid to make it scroll when I click the scrollbar. I'm sure it's doable because SchollViewer is already doing it. Your tip is much appreciated.
UPDATE:
In fact, what I want is to create a Excel-spreadsheet like control. I created the spreadsheet using Grid layout and it seems working fine. However, I run into a problem in scrolling. Adding a ScrollViewer around the Grid will make the whole Grid scroll. However, I want to be able to freeze some rows and/or columns from scrolling. Also, using ScrollViewer, the horizontal scrollbar covers the whole bottom. But, like in Excel, I'd like to leave some space for adding some tabs. Is this possible just through restyling of the ScrollViewer?
I find a post at http://social.msdn.microsoft.com/Forums/en/wpf/thread/e495a0cb-0104-4475-8627-3b40cd617fc1 which suggests to split grid in several sub-grids to achieve freezing headers. However, it doesn't work well if you have many columns. Furthermore, this approach is not flexible enough to allow user to choose freezing area.
Styling scrollbars can be a bit tricky, but I have a style to get you started (based of Expression style), you can just remove the bits you dont need/want and change colors etc.
Scollbar style example:
<Color x:Key="MainColor">#FF595959</Color>
<Color x:Key="BlackColor">#FF000000</Color>
<Color x:Key="WhiteColor">#FFFFFFFF</Color>
<SolidColorBrush x:Key="NormalBrush" Color="{StaticResource MainColor}" />
<SolidColorBrush x:Key="NormalBorderBrush" Color="#FF393939" />
<SolidColorBrush x:Key="GlyphBrush" Color="#FFD1D1D1" />
<LinearGradientBrush x:Key="PressedBrush" EndPoint="0.5,0.971" StartPoint="0.5,0.042">
<GradientStop Color="#4C000000" Offset="0" />
<GradientStop Color="#26FFFFFF" Offset="1" />
<GradientStop Color="#4C000000" Offset="0.467" />
<GradientStop Color="#26FFFFFF" Offset="0.479" />
</LinearGradientBrush>
<Style TargetType="{x:Type RepeatButton}" BasedOn="{x:Null}">
<Setter Property="Background" Value="{DynamicResource NormalBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<ControlTemplate.Resources>
<Storyboard x:Key="HoverOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0.8"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HoverOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.3"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="PressedOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0.1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="PressedOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.3"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid>
<Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" Opacity="1" />
<ContentPresenter HorizontalAlignment="Center" x:Name="ContentPresenter" VerticalAlignment="Center" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" Opacity="0.3" Height="Auto" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true" />
<Trigger Property="IsMouseOver" Value="true">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HoverOff}" x:Name="HoverOff_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HoverOn}"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource PressedOff}" x:Name="PressedOff_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource PressedOn}" x:Name="PressedOn_BeginStoryboard"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="ContentPresenter" Value="0.1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NuclearThumbStyle" TargetType="{x:Type Thumb}" BasedOn="{x:Null}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<ControlTemplate.Resources>
<Storyboard x:Key="HoverOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="HoverRectangle" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0.8"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HoverOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="HoverRectangle" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.3"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="PressedOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PressedRectangle" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0.1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="PressedOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PressedRectangle" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.3"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid Margin="0,0,0,0" x:Name="Grid">
<Rectangle HorizontalAlignment="Stretch" x:Name="HoverRectangle" VerticalAlignment="Stretch" Width="Auto" Height="Auto" RadiusX="3" RadiusY="4" Stroke="{x:Null}" Margin="4.5,-2,4.5,-2" Opacity="0.3" MinHeight="10">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource WhiteColor}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle HorizontalAlignment="Stretch" x:Name="PressedRectangle" VerticalAlignment="Stretch" Width="Auto" Height="Auto" RadiusX="3" RadiusY="4" Stroke="{x:Null}" Margin="4.5,-2,4.5,-2" Opacity="0.3" MinHeight="10">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource WhiteColor}" />
</Rectangle.Fill>
</Rectangle>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True" />
<Trigger Property="IsMouseOver" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HoverOff}" x:Name="HoverOff_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HoverOn}"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False" >
<Setter Property="Opacity" TargetName="Grid" Value="0.1"/>
</Trigger>
<Trigger Property="IsDragging" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource PressedOff}" x:Name="PressedOff_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource PressedOn}" x:Name="PressedOn_BeginStoryboard"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NuclearScrollRepeatButtonStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Grid>
<Rectangle Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{TemplateBinding BorderThickness}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsFlicksEnabled" Value="false" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="GridRoot" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Background="{DynamicResource NormalBrush}">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="18" />
<RowDefinition Height="0.00001*" />
<RowDefinition MaxHeight="18" />
</Grid.RowDefinitions>
<RepeatButton x:Name="DecreaseRepeat" Command="ScrollBar.LineUpCommand" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}">
<Grid Margin="0,0,0,0">
<Path Margin="4.742,3.997,4.946,5.327" VerticalAlignment="Stretch" Height="Auto" Fill="{DynamicResource GlyphBrush}" Stretch="Fill" Stroke="{DynamicResource GlyphBrush}" StrokeThickness="1" Data="M5.2422477,11.132184 L11.5544,11.132184 8.6412958,4.4969033 z" x:Name="DecreaseArrow" />
</Grid>
</RepeatButton>
<Track Grid.Row="1" x:Name="PART_Track" Orientation="Vertical" IsDirectionReversed="true">
<Track.Thumb>
<Thumb Style="{DynamicResource NuclearThumbStyle}" Background="{x:Null}" Foreground="{x:Null}" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton x:Name="PageUp" Style="{DynamicResource NuclearScrollRepeatButtonStyle}" Command="ScrollBar.PageDownCommand" />
</Track.IncreaseRepeatButton>
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="PageDown" Style="{DynamicResource NuclearScrollRepeatButtonStyle}" Command="ScrollBar.PageUpCommand" />
</Track.DecreaseRepeatButton>
</Track>
<RepeatButton Grid.Row="2" x:Name="IncreaseRepeat" Command="ScrollBar.LineDownCommand">
<Grid>
<Path Margin="4.742,3.997,4.946,5.327" x:Name="IncreaseArrow" VerticalAlignment="Stretch" Height="Auto" Fill="{DynamicResource GlyphBrush}" Stretch="Fill" Stroke="{DynamicResource GlyphBrush}" StrokeThickness="1" Data="M5.2422477,11.132184 L11.5544,11.132184 8.6412958,4.4969033 z" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="180" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
</RepeatButton>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="LayoutTransform" TargetName="GridRoot">
<Setter.Value>
<RotateTransform Angle="-90" />
</Setter.Value>
</Setter>
<Setter TargetName="PART_Track" Property="Orientation" Value="Vertical" />
<Setter Property="Command" Value="ScrollBar.LineLeftCommand" TargetName="DecreaseRepeat" />
<Setter Property="Command" Value="ScrollBar.LineRightCommand" TargetName="IncreaseRepeat" />
<Setter Property="Command" Value="ScrollBar.PageLeftCommand" TargetName="PageDown" />
<Setter Property="Command" Value="ScrollBar.PageRightCommand" TargetName="PageUp" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Style:
I have the following XAML style for my button :
<Style TargetType="{x:Type Button}">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="BtnBorder" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}" CornerRadius="5" VerticalAlignment="Center" BorderBrush="White" BorderThickness="0" ClipToBounds="True" HorizontalAlignment="Center">
<Grid Width="{Binding ElementName=BtnBorder, Path=ActualWidth}">
<Rectangle Name="BtnRect" RadiusX="6" RadiusY="5" Opacity="0.2" Fill="White" />
<Rectangle x:Name="progressIndicator" Width="0" HorizontalAlignment="Left" RadiusX="8" RadiusY="8" Margin="1">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<GradientStop Color="Transparent" Offset="0" />
<GradientStop Color="#88FFFFFF" Offset="0.945" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="BtnCP" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BtnRect" Storyboard.TargetProperty="Opacity" From="0.25" To="0.5" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BtnRect" Storyboard.TargetProperty="Opacity" From="0.5" To="0.25" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="BtnBorder" Property="BorderThickness" Value="1.3" />
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="progressIndicator" Storyboard.TargetProperty="Width" From="0" To="300" Duration="0:0:5" AutoReverse="True" RepeatBehavior="5x" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="BtnBorder" Property="BorderThickness" Value="1.5,0,1.5,0" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="True" />
<Condition Property="IsPressed" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="BtnBorder" Property="BorderThickness" Value="1.3" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can i control the animation of the Rectangle property of my button through code behind upon clicking the button.
The Rectangle named "progressIndicator" is to grow in width through animation when the user clicks the button.
Currently animation starts in Xaml. Why do you want to it in code-behind?
I want a checkbox that is invisible in its unchecked state. While unchecked, hovering the mouse over it will cause it to animate to 0.3 transparency.
When the mouse pointer leaves the checkbox and if it is still unchecked, it animates back to 0 transparency.
When checked, it will be at fully visible, ie. transparency = 1.
All my attempts so far have been unsuccessful, I think due to the mouse-over rule. When my checkbox becomes checked, the mouse-over still causes a fade to 0.3 and on mouse-leave, it becomes invisible.
I tried using triggers, multitriggers, the VSM, but I can't figure out how to code the behaviour I want without conflicts.
Code:
Here is the Triggers approach. It's gone through so many iterations, I can't even remember if this was my initial approach.
I also have a VSM approach, just say if you want the code for that one too.
Control Template (I took the sample provided in MSDN and just modified it)
<Style x:Key="{x:Type CheckBox}"
TargetType="{x:Type CheckBox}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="FocusVisualStyle"
Value="{DynamicResource CheckBoxFocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Border x:Name="Border"
Width="80"
Height="80"
CornerRadius="0"
BorderThickness="1">
<Grid>
<Path Visibility="Visible"
Width="100"
Height="100"
x:Name="CheckBorder"
SnapsToDevicePixels="False"
StrokeThickness="9"
Opacity="0"
Data="M 0 30 C 2,29 10,30 14,39 M 15,40 C 5,31 55,10 45,20 ">
<Path.Stroke>
<SolidColorBrush Color="Black" />
</Path.Stroke>
</Path>
<Path Visibility="Visible"
Width="100"
Height="100"
x:Name="CheckMark"
Opacity="0"
SnapsToDevicePixels="False"
StrokeThickness="6"
Data="M 1 30 C 2,29 10,30 14,39 M 15,39 C 5,31 55,10 45,20 ">
<Path.Stroke>
<SolidColorBrush Color="#FF0C9D0C" />
</Path.Stroke>
</Path>
<Path Visibility="Collapsed"
Width="100"
Height="100"
x:Name="InderminateMark"
SnapsToDevicePixels="False"
StrokeThickness="5"
Data="M 0 0 L 50 50">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
</Grid>
</Border>
</BulletDecorator.Bullet>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckBorder" To="0.3" Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckMark" To="0.3" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckBorder" To="0" Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckMark" To="0" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Opacity" TargetName="CheckBorder" Value="1"/>
<Setter Property="Opacity" TargetName="CheckMark" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Declaration
<CheckBox Width="100" Height="100">Hello</CheckBox>
Well, I just went with a somewhat diabolical workaround. The mouse-over stuff works with a dummy background Path/image, while the check & uncheck work with the main Path/image.
Kaxaml Code dump:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.Resources>
<Style x:Key="{x:Type CheckBox}"
TargetType="{x:Type CheckBox}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="FocusVisualStyle"
Value="{DynamicResource CheckBoxFocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Border x:Name="Border"
Width="80"
Height="80"
CornerRadius="0"
BorderThickness="1">
<Grid>
<Path Visibility="Visible"
Width="100"
Height="100"
x:Name="Dummy"
SnapsToDevicePixels="False"
StrokeThickness="9"
Opacity="0"
Data="M 0 30 C 2,29 10,30 14,39 M 15,40 C 5,31 55,10 45,20 ">
<Path.Stroke>
<SolidColorBrush Color="#FF224502" />
</Path.Stroke>
</Path>
<Path Visibility="Visible"
Width="100"
Height="100"
x:Name="CheckBorder"
SnapsToDevicePixels="False"
StrokeThickness="9"
Opacity="0"
Data="M 0 30 C 2,29 10,30 14,39 M 15,40 C 5,31 55,10 45,20 ">
<Path.Stroke>
<SolidColorBrush Color="Black" />
</Path.Stroke>
</Path>
<Path Visibility="Visible"
Width="100"
Height="100"
x:Name="CheckMark"
Opacity="0"
SnapsToDevicePixels="False"
StrokeThickness="6"
Data="M 1 30 C 2,29 10,30 14,39 M 15,39 C 5,31 55,10 45,20 ">
<Path.Stroke>
<SolidColorBrush Color="#FF0C9D0C" />
</Path.Stroke>
</Path>
<Path Visibility="Collapsed"
Width="100"
Height="100"
x:Name="InderminateMark"
SnapsToDevicePixels="False"
StrokeThickness="5"
Data="M 0 0 L 50 50">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
</Grid>
</Border>
</BulletDecorator.Bullet>
</BulletDecorator>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Dummy" To="0.3" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Dummy" To="0" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</MultiTrigger.ExitActions>
</MultiTrigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="CheckBorder" Property="Opacity" Value="1"/>
<Setter TargetName="CheckMark" Property="Opacity" Value="1"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="CheckBorder" Property="Opacity" Value="0"/>
<Setter TargetName="CheckMark" Property="Opacity" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<CheckBox Width="100" Height="100">Hello</CheckBox>
</Grid>
</Page>
Check the location of your triggers: put the IsChecked trigger under the IsMouseOver trigger.