First of all, please bear with me. I'm completely new to StackOverflow, WPF, and XAML. Anyway, I watched some tutorials and understand the basics of Animations with StoryBoards. I already created some Double- and ColorAnimations.
Now I want a border to appear around a button when the mouse is over it (with an animation), but I can't get it to work. First, this is the style applied to the button.
<Style x:Key="DarkButtonNoBG" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="DarkGray" />
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<Border BorderThickness="0" BorderBrush="White">
<ContentPresenter x:Name="MyContentPresenter"
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
...
</Style>
The border animation works when I remove the style, but then the background color of the button changes to light blue when hovered over and I can't override it with a color animation. This is my button control:
<Button Style="{StaticResource DarkButtonNoBG}" x:Name="btnStart" Grid.Row="4" Height="40" Width="150"
Click="btnStart_Click" Content="Start" FontSize="17" Foreground="White" BorderThickness="0" BorderBrush="White">
<!--#region Animation-->
<Button.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" From="150" To="165" Duration="0:0:0.4" DecelerationRatio="1"/>
<DoubleAnimation Storyboard.TargetProperty="Height" From="40" To="50" Duration="0:0:0.4" DecelerationRatio="1"/>
<DoubleAnimation Storyboard.TargetProperty="FontSize" From="17" To="20" Duration="0:0:0.4" DecelerationRatio="1"/>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Transparent" To="#88444444"
Duration="0:0:0.4" DecelerationRatio="1"/>
**<ThicknessAnimation Storyboard.TargetProperty="BorderThickness" To="2,2,2,2" Duration="0:0:1"/>**
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" From="165" To="150" Duration="0:0:0.4" DecelerationRatio="1"/>
<DoubleAnimation Storyboard.TargetProperty="Height" From="50" To="40" Duration="0:0:0.4" DecelerationRatio="1"/>
<DoubleAnimation Storyboard.TargetProperty="FontSize" From="20" To="17" Duration="0:0:0.4" DecelerationRatio="1"/>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="#88444444" To="Transparent"
Duration="0:0:0.4" DecelerationRatio="1"/>
**<ThicknessAnimation Storyboard.TargetProperty="BorderThickness"
To="0,0,0,0" Duration="0:0:0.4"/>**
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
<!--#endregion-->
</Button>
The Width, Height, FontSize and Background Animations work perfectly but it seems I can't access the BorderThickness
property because it is in the template.
I tried moving the ThicknessAnimation
to the style, so I added this to the style:
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="#88444444"
Duration="0:0:0.4" DecelerationRatio="1"/>
**<ThicknessAnimation Storyboard.TargetProperty="BorderThickness" To="2,2,2,2" Duration="0:0:0.5"/>**
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="Transparent"
Duration="0:0:0.4" DecelerationRatio="1"/>
**<ThicknessAnimation Storyboard.TargetProperty="BorderThickness" To="2,2,2,2" Duration="0:0:0.5"/>**
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
The ColorAnimation
works but the ThicknessAnimation
still doesn't. Perhaps I need to animate the BorderThickness
Property that is in the Template
, but I don't know how to access it.
I also tried animating the BorderThickness with 4 DoubleAnimations like this:
<DoubleAnimation Storyboard.TargetProperty="BorderThickness.Top" To="2" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetProperty="BorderThickness.Bottom" To="2" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetProperty="BorderThickness.Left" To="2" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetProperty="BorderThickness.Right" To="2" Duration="0:0:0.5"/>
But this throws an Exception:
**System.InvalidOperationException**: ''BorderThickness' property does not point to a DependencyObject in path 'BorderThickness.Top'.'
Sorry if I messed up the formatting. If I did, I will try to correct it. Again, this is my first question. Thanks in advance!
EDIT: For now, I just added the border on MouseOver without an animation:
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<Border BorderThickness="0.5" BorderBrush="White">
<ContentPresenter x:Name="MyContentPresenter"
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
This actually works well enough, but I'd still like to know how I could animate it...
You need to bind the borders BorderThickness
to the templated parent.
<ControlTemplate TargetType="{x:Type Button}">
<Grid Background="{TemplateBinding Background}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="White">
<ContentPresenter x:Name="MyContentPresenter"
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</Grid>
</ControlTemplate>
You've hard coded the BorderThickness
within your control template which means that changing it through means such as within the button declaration, e.g. <Button BorderThickness="2"/>
will not effect the border in any way.