Reputation: 107
With respect to the code below, can anyone tell me why when a button is in normal state as well as in focused state, the button does not bounce? In other words, shouldn't a button bounce anytime it gets focused state, regardless whether it is pressed or not ?
<Window x:Class="ButtonTemplateUsingVSM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="249" Width="619">
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid RenderTransformOrigin=".5,.5">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal"/>
<VisualState Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="outerCircle"
Storyboard.TargetProperty="(Ellipse.Fill).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)"
To="Orange" Duration="0:0:.4"/>
</Storyboard>
</VisualState>
<VisualState Name="Pressed">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To=".9" Duration="0"/>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To=".9" Duration="0"/>
</Storyboard>
</VisualState>
<VisualState Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="outerCircle"
Storyboard.TargetProperty="(Ellipse.Fill).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)"
To="Gray" Duration="0:0:.4"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup Name="FocusStates">
<VisualState Name="Unfocused"/>
<VisualState Name="Focused">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Grid.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)"
To="-20" AutoReverse="True" RepeatBehavior="Forever" Duration="0:0:.4">
<DoubleAnimation.EasingFunction>
<QuadraticEase/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="scaleTransform"/>
<TranslateTransform x:Name="translateTransform"/>
</TransformGroup>
</Grid.RenderTransform>
<Ellipse x:Name="outerCircle">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0"
Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background.Color}"/>
<GradientStop x:Name="highlightGradientStop" Offset="1" Color="Red"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse RenderTransformOrigin=".5,.5">
<Ellipse.RenderTransform>
<ScaleTransform ScaleX=".8" ScaleY=".8"/>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="White"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Viewbox>
<ContentPresenter Margin="{TemplateBinding Padding}"/>
</Viewbox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel Orientation="Horizontal">
<Button Height="200" Width="200" FontSize="20" Padding="20" Margin="5">OK</Button>
<Button Height="200" Width="200" FontSize="20" Padding="20" Margin="5">OK</Button>
<Button Height="200" Width="200" FontSize="20" Padding="20" Margin="5">OK</Button>
<Button Height="200" Width="200" FontSize="20" IsEnabled="False" Padding="20" Margin="5">OK</Button>
<Button Height="200" Width="200" FontSize="20" Padding="20" Margin="5">OK</Button>
</StackPanel>
</Window>
namespace ButtonTemplateUsingVSM
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
Upvotes: 0
Views: 2326
Reputation: 10162
By default, a button gets focus only when it's pressed (unless you change it in code). You can also obtain a keyboard focus. Therefore, your bouncing animation will only work when one of those buttons is pressed, due to it being set only for the Focused
state:
<VisualStateGroup Name="FocusStates">
<VisualState Name="Unfocused"/> <!--Right here-->
<VisualState Name="Focused">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Grid.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)"
To="-20" AutoReverse="True" RepeatBehavior="Forever"
Duration="0:0:.4">
<DoubleAnimation.EasingFunction>
<QuadraticEase/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
As you can see, Unfocused
VisualState
does not have any animation pertaining to it. So, unless one of those buttons gets the focus, it won't bounce. It'll simply change colors from red to orange per the MouseOver
VisualState
.
I think this would be a good read for your: MSDN Focus Overview
EDIT:
Explanation for discussion in the comments.
XAML:
<Window x:Class="Focus.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Content="Button 1" HorizontalAlignment="Center" Width="75" Margin="20" GotFocus="Button1_GotFocus"/>
<Button Content="Button 2" HorizontalAlignment="Center" Width="75" GotFocus="Button2_GotFocus"/>
</StackPanel>
</Window>
Code-Behind:
using System.Windows;
namespace Focus
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button1_GotFocus(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button 1 Focused");
}
private void Button2_GotFocus(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button 2 Focused");
}
}
}
Upvotes: 2